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;
}
}