using System.Diagnostics.CodeAnalysis;
namespace Barotrauma;
///
/// Discriminated union of three types.
/// Essentially the same thing as Either<T1, T2>, except for three types instead of two types.
///
public readonly struct OneOf
where T1 : notnull
where T2 : notnull
where T3 : notnull
{
private readonly Option value1;
private readonly Option value2;
private readonly Option value3;
private OneOf(Option value1, Option value2, Option value3)
{
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
}
public static implicit operator OneOf(T1 value1)
=> new OneOf(value1: Option.Some(value1), value2: Option.None, value3: Option.None);
public static implicit operator OneOf(T2 value2)
=> new OneOf(value1: Option.None, value2: Option.Some(value2), value3: Option.None);
public static implicit operator OneOf(T3 value3)
=> new OneOf(value1: Option.None, value2: Option.None, value3: Option.Some(value3));
public bool TryGet([NotNullWhen(returnValue: true)] out T1? t1)
=> value1.TryUnwrap(out t1);
public bool TryGet([NotNullWhen(returnValue: true)] out T2? t2)
=> value2.TryUnwrap(out t2);
public bool TryGet([NotNullWhen(returnValue: true)] out T3? t3)
=> value3.TryUnwrap(out t3);
private static string ObjectToStringWithType(T obj)
=> $"{obj}: {typeof(T).Name}";
public override string ToString()
=> $"OneOf<{typeof(T1).Name}, {typeof(T2).Name}, {typeof(T3).Name}>("
+ value1.Select(ObjectToStringWithType)
.Fallback(value2.Select(ObjectToStringWithType))
.Fallback(value3.Select(ObjectToStringWithType))
.Fallback("None")
+ ")";
}