using OneOf; namespace InkBlot.ParseHierarchy; [GenerateOneOf] public partial class MultiDivert : OneOfBase, IStoryNode; public record Identifier(string[] Elements /* TODO: expressions */) { public virtual bool Equals(Identifier? other) { return other is not null && Elements.SequenceEqual(other.Elements); } public override string ToString() { return "Identifier(" + string.Join('.', Elements) + ")"; } public override int GetHashCode() { return Elements.GetHashCode(); } } // <- thread_name public record ThreadDivert(Identifier Identifier) : IStoryNode { public override string ToString() { return $"ThreadDivert({Identifier})"; } } [GenerateOneOf] public partial class TunnelListEnding : OneOfBase; public record TunnelListEndingDivert(Identifier? Divert); public record TunnelListEndingReturnFromTunnel(Identifier? Divert); /// /// A sequence of zero or more tunnels, potentially ending in a divert, and potentially providing a tunnel replacement. /// /// -> // [], divert(null) /// ->-> // [], returnFromTunnel(null) /// -> divertName // [], divert(divertName) /// ->-> divertName // [], returnFromTunnel(divertName) /// -> tunnelName -> // [tunnelName], divert(null) /// -> tunnelName -> divertName // [tunnelName], divert(divertName) /// -> tunnelName1 -> tunnelName2 -> // [tunnelName1, tunnelName2], divert(null) /// -> tunnelName1 -> tunnelName2 ->-> // [tunnelName1, tunnelName2], returnFromTunnel(null) /// -> tunnelName1 -> tunnelName2 ->-> divertName // [tunnelName1, tunnelName2], returnFromTunnel(divertName) /// /// public record TunnelsAndDivertsList(Identifier[] TunnelIdentifiers, TunnelListEnding Ending) : IStoryNode { private const string Sep = ", "; public virtual bool Equals(TunnelsAndDivertsList? other) { return other is not null && Ending.Equals(other.Ending) && TunnelIdentifiers.SequenceEqual(other.TunnelIdentifiers); } public override int GetHashCode() { return HashCode.Combine(TunnelIdentifiers, Ending); } public override string ToString() { return $"TunnelsAndDivertsList({string.Join(Sep, TunnelIdentifiers.Select(i => i.ToString()))}, {Ending})"; } }