using MsgPack; using Ryujinx.Ava.Utilities.AppLibrary; using System; namespace Ryujinx.Ava.Utilities.PlayReport { /// /// The input data to a , /// containing the currently running application's , /// and the matched from the Play Report. /// public class Value { /// /// The currently running application's . /// public ApplicationMetadata Application { get; init; } /// /// 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(); } #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 . /// 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 FormattedValue Unhandled => default; /// /// Return this to suggest the caller reset the value it's using the for. /// public static FormattedValue ForceReset => new() { Handled = true, Reset = true }; /// /// A delegate singleton you can use to always return in a . /// public static readonly ValueFormatter SingleAlwaysResets = _ => ForceReset; /// /// A delegate singleton you can use to always return in a . /// public static readonly MultiValueFormatter MultiAlwaysResets = _ => 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 ValueFormatter AlwaysReturns(string formattedValue) => _ => formattedValue; } }