using System.Diagnostics.CodeAnalysis; namespace NubLang; public readonly struct Variant where T1 : notnull where T2 : notnull { public Variant() { throw new InvalidOperationException("Variant must be initialized with a value"); } public Variant(T1 value) { _value = value; } public Variant(T2 value) { _value = value; } private readonly object _value; public void Match(Action on1, Action on2) { switch (_value) { case T1 v1: on1(v1); break; case T2 v2: on2(v2); break; default: throw new InvalidCastException(); } } public T Match(Func on1, Func on2) { return _value switch { T1 v1 => on1(v1), T2 v2 => on2(v2), _ => throw new InvalidCastException() }; } public bool IsCase1([NotNullWhen(true)] out T1? value) { if (_value is T1 converted) { value = converted; return true; } value = default; return false; } public bool IsCase2([NotNullWhen(true)] out T2? value) { if (_value is T2 converted) { value = converted; return true; } value = default; return false; } public static implicit operator Variant(T1 value) => new(value); public static implicit operator Variant(T2 value) => new(value); }