One C# type per Rust type, keys in the crate's slot order. Unions are abstract classes with an internal constructor and sealed arms; unit arms are shared instances. ThingDomain owns the four domains and ThingKeys the key grammar. CommandResult is built by four factories only; its constructor is private. Builds against CultLib b3bd8dd5 through CultLibRoot. Tests follow in the next commit; this one builds. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
330 lines
7.2 KiB
C#
330 lines
7.2 KiB
C#
using System.Collections.Generic;
|
|
using GameCult.Caching;
|
|
using MessagePack;
|
|
|
|
namespace GameCult.Thing.Contract;
|
|
|
|
[Union(0, typeof(TextLiteral))]
|
|
[Union(1, typeof(TextSourceBound))]
|
|
[Union(2, typeof(TextSourceParam))]
|
|
public abstract class TextSource
|
|
{
|
|
internal TextSource() { }
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class TextLiteral : TextSource
|
|
{
|
|
[Key(0)] public string Value { get; }
|
|
|
|
public TextLiteral(string value)
|
|
{
|
|
Value = value;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class TextSourceBound : TextSource
|
|
{
|
|
[Key(0)] public StateSource Source { get; }
|
|
[Key(1)] public MemberPath Member { get; }
|
|
[Key(2)] public Format? Format { get; }
|
|
|
|
public TextSourceBound(StateSource source, MemberPath member, Format? format)
|
|
{
|
|
Source = source;
|
|
Member = member;
|
|
Format = format;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class TextSourceParam : TextSource
|
|
{
|
|
[Key(0)] public string Name { get; }
|
|
|
|
public TextSourceParam(string name)
|
|
{
|
|
Name = name;
|
|
}
|
|
}
|
|
|
|
[Union(0, typeof(NumberLiteral))]
|
|
[Union(1, typeof(NumberSourceBound))]
|
|
[Union(2, typeof(NumberSourceParam))]
|
|
public abstract class NumberSource
|
|
{
|
|
internal NumberSource() { }
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class NumberLiteral : NumberSource
|
|
{
|
|
[Key(0)] public double Value { get; }
|
|
|
|
public NumberLiteral(double value)
|
|
{
|
|
Value = value;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class NumberSourceBound : NumberSource
|
|
{
|
|
[Key(0)] public StateSource Source { get; }
|
|
[Key(1)] public MemberPath Member { get; }
|
|
[Key(2)] public Format? Format { get; }
|
|
|
|
public NumberSourceBound(StateSource source, MemberPath member, Format? format)
|
|
{
|
|
Source = source;
|
|
Member = member;
|
|
Format = format;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class NumberSourceParam : NumberSource
|
|
{
|
|
[Key(0)] public string Name { get; }
|
|
|
|
public NumberSourceParam(string name)
|
|
{
|
|
Name = name;
|
|
}
|
|
}
|
|
|
|
[Union(0, typeof(BoolLiteral))]
|
|
[Union(1, typeof(BoolSourceBound))]
|
|
[Union(2, typeof(BoolSourceParam))]
|
|
public abstract class BoolSource
|
|
{
|
|
internal BoolSource() { }
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class BoolLiteral : BoolSource
|
|
{
|
|
[Key(0)] public bool Value { get; }
|
|
|
|
public BoolLiteral(bool value)
|
|
{
|
|
Value = value;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class BoolSourceBound : BoolSource
|
|
{
|
|
[Key(0)] public StateSource Source { get; }
|
|
[Key(1)] public MemberPath Member { get; }
|
|
[Key(2)] public Format? Format { get; }
|
|
|
|
public BoolSourceBound(StateSource source, MemberPath member, Format? format)
|
|
{
|
|
Source = source;
|
|
Member = member;
|
|
Format = format;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class BoolSourceParam : BoolSource
|
|
{
|
|
[Key(0)] public string Name { get; }
|
|
|
|
public BoolSourceParam(string name)
|
|
{
|
|
Name = name;
|
|
}
|
|
}
|
|
|
|
[Union(0, typeof(StateRef))]
|
|
[Union(1, typeof(StateSourceItem))]
|
|
public abstract class StateSource
|
|
{
|
|
internal StateSource() { }
|
|
public static StateSource Item => StateSourceItem.Instance;
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class StateRef : StateSource
|
|
{
|
|
[Key(0)] public string? Provider { get; }
|
|
[Key(1)] public string Schema { get; }
|
|
[Key(2)] public string Key { get; }
|
|
|
|
public StateRef(string? provider, string schema, string key)
|
|
{
|
|
Provider = provider;
|
|
Schema = schema;
|
|
Key = key;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject(AllowPrivate = true)]
|
|
public sealed class StateSourceItem : StateSource
|
|
{
|
|
internal static readonly StateSourceItem Instance = new StateSourceItem();
|
|
|
|
[SerializationConstructor] private StateSourceItem() { }
|
|
}
|
|
|
|
[Union(0, typeof(MemberName))]
|
|
[Union(1, typeof(MemberIndex))]
|
|
public abstract class MemberStep
|
|
{
|
|
internal MemberStep() { }
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class MemberName : MemberStep
|
|
{
|
|
[Key(0)] public string Name { get; }
|
|
|
|
public MemberName(string name)
|
|
{
|
|
Name = name;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class MemberIndex : MemberStep
|
|
{
|
|
[Key(0)] public int Index { get; }
|
|
|
|
public MemberIndex(int index)
|
|
{
|
|
Index = ThingDomain.Count(index);
|
|
}
|
|
}
|
|
|
|
[Union(0, typeof(NumberFormat))]
|
|
[Union(1, typeof(FormatDuration))]
|
|
[Union(2, typeof(FormatTimestamp))]
|
|
[Union(3, typeof(AffixFormat))]
|
|
public abstract class Format
|
|
{
|
|
internal Format() { }
|
|
public static Format Duration => FormatDuration.Instance;
|
|
public static Format Timestamp => FormatTimestamp.Instance;
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class NumberFormat : Format
|
|
{
|
|
[Key(0)] public int Precision { get; }
|
|
[Key(1)] public bool Percent { get; }
|
|
[Key(2)] public string? Unit { get; }
|
|
|
|
public NumberFormat(int precision, bool percent, string? unit)
|
|
{
|
|
Precision = ThingDomain.Count(precision);
|
|
Percent = percent;
|
|
Unit = unit;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject(AllowPrivate = true)]
|
|
public sealed class FormatDuration : Format
|
|
{
|
|
internal static readonly FormatDuration Instance = new FormatDuration();
|
|
|
|
[SerializationConstructor] private FormatDuration() { }
|
|
}
|
|
|
|
[MessagePackObject(AllowPrivate = true)]
|
|
public sealed class FormatTimestamp : Format
|
|
{
|
|
internal static readonly FormatTimestamp Instance = new FormatTimestamp();
|
|
|
|
[SerializationConstructor] private FormatTimestamp() { }
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class AffixFormat : Format
|
|
{
|
|
[Key(0)] public string Prefix { get; }
|
|
[Key(1)] public string Suffix { get; }
|
|
|
|
public AffixFormat(string prefix, string suffix)
|
|
{
|
|
Prefix = prefix;
|
|
Suffix = suffix;
|
|
}
|
|
}
|
|
|
|
[Union(0, typeof(RecordsSource))]
|
|
[Union(1, typeof(CollectionSourceMember))]
|
|
[Union(2, typeof(CollectionSourceParam))]
|
|
public abstract class CollectionSource
|
|
{
|
|
internal CollectionSource() { }
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class RecordsSource : CollectionSource
|
|
{
|
|
[Key(0)] public string? Provider { get; }
|
|
[Key(1)] public string Schema { get; }
|
|
[Key(2)] public string KeyPrefix { get; }
|
|
|
|
public RecordsSource(string? provider, string schema, string keyPrefix)
|
|
{
|
|
Provider = provider;
|
|
Schema = schema;
|
|
KeyPrefix = keyPrefix;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class CollectionSourceMember : CollectionSource
|
|
{
|
|
[Key(0)] public StateSource Source { get; }
|
|
[Key(1)] public MemberPath Member { get; }
|
|
[Key(2)] public Format? Format { get; }
|
|
|
|
public CollectionSourceMember(StateSource source, MemberPath member, Format? format)
|
|
{
|
|
Source = source;
|
|
Member = member;
|
|
Format = format;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class CollectionSourceParam : CollectionSource
|
|
{
|
|
[Key(0)] public string Name { get; }
|
|
|
|
public CollectionSourceParam(string name)
|
|
{
|
|
Name = name;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class Bind
|
|
{
|
|
[Key(0)] public StateSource Source { get; }
|
|
[Key(1)] public MemberPath Member { get; }
|
|
[Key(2)] public Format? Format { get; }
|
|
|
|
public Bind(StateSource source, MemberPath member, Format? format)
|
|
{
|
|
Source = source;
|
|
Member = member;
|
|
Format = format;
|
|
}
|
|
}
|
|
|
|
[MessagePackObject]
|
|
public sealed class MemberPath
|
|
{
|
|
[Key(0)] public List<MemberStep> Steps { get; }
|
|
|
|
public MemberPath(List<MemberStep> steps)
|
|
{
|
|
Steps = steps;
|
|
}
|
|
}
|