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