using MsgPack; using System; using System.Collections.Generic; using System.Linq; namespace Ryujinx.Ava.Systems.PlayReport { /// /// The base input data to a ValueFormatter delegate, /// and the matched from the Play Report. /// public readonly struct Value { public Value(MessagePackObject packedValue) { PackedValue = packedValue; } /// /// The matched value from the Play Report. /// public MessagePackObject PackedValue { get; init; } /// /// Access the as its underlying .NET type.
/// /// Does not seem to work well with comparing numeric types, /// so use XValue properties for that. ///
public object BoxedValue => PackedValue.ToObject(); public override string ToString() { object boxed = BoxedValue; return boxed == null ? "null" : boxed.ToString(); } public static implicit operator Value(MessagePackObject matched) => new(matched); public static Value[] ConvertPackedObjects(IEnumerable packObjects) => packObjects.Select(packObject => new Value(packObject)).ToArray(); public static Dictionary ConvertPackedObjectMap(Dictionary packObjects) => packObjects.ToDictionary( x => x.Key, x => new Value(x.Value) ); #region AsX accessors public bool BooleanValue => PackedValue.AsBoolean(); public byte ByteValue => PackedValue.AsByte(); public sbyte SByteValue => PackedValue.AsSByte(); public short ShortValue => PackedValue.AsInt16(); public ushort UShortValue => PackedValue.AsUInt16(); public int IntValue => PackedValue.AsInt32(); public uint UIntValue => PackedValue.AsUInt32(); public long LongValue => PackedValue.AsInt64(); public ulong ULongValue => PackedValue.AsUInt64(); public float FloatValue => PackedValue.AsSingle(); public double DoubleValue => PackedValue.AsDouble(); public string StringValue => PackedValue.AsString(); public Span BinaryValue => PackedValue.AsBinary(); #endregion } /// /// A potential formatted value returned by a ValueFormatter delegate. /// public readonly struct FormattedValue { /// /// Was any handler able to match anything in the Play Report? /// public bool Handled { get; private init; } /// /// Did the handler request the caller of the to reset the existing value? /// public bool Reset { get; private init; } /// /// The formatted value, only present if is true, and is false. /// public string FormattedString { get; private init; } /// /// The intended path of execution for having a string to return: simply return the string. /// This implicit conversion will make the struct for you.

/// /// If the input is null, is returned. ///
/// The formatted string value. /// The automatically constructed struct. public static implicit operator FormattedValue(string formattedValue) => formattedValue is not null ? new FormattedValue { Handled = true, FormattedString = formattedValue } : Unhandled; public override string ToString() { if (!Handled) return ""; if (Reset) return ""; return FormattedString; } /// /// Return this to tell the caller there is no value to return. /// public static readonly FormattedValue Unhandled = default; /// /// Return this to suggest the caller reset the value it's using the for. /// public static readonly FormattedValue ForceReset = new() { Handled = true, Reset = true }; /// /// A delegate singleton you can use to always return in a . /// public static readonly SingleValueFormatter SingleAlwaysResets = _ => ForceReset; /// /// A delegate singleton you can use to always return in a . /// public static readonly MultiValueFormatter MultiAlwaysResets = _ => ForceReset; /// /// A delegate singleton you can use to always return in a . /// public static readonly SparseMultiValueFormatter SparseMultiAlwaysResets = _ => ForceReset; /// /// A delegate factory you can use to always return the specified /// in a . /// /// The string to always return for this delegate instance. public static SingleValueFormatter SingleAlwaysReturns(string formattedValue) => _ => formattedValue; /// /// A delegate factory you can use to always return the specified /// in a . /// /// The string to always return for this delegate instance. public static MultiValueFormatter MultiAlwaysReturns(string formattedValue) => _ => formattedValue; /// /// A delegate factory you can use to always return the specified /// in a . /// /// The string to always return for this delegate instance. public static SparseMultiValueFormatter SparseMultiAlwaysReturns(string formattedValue) => _ => formattedValue; } }