#nullable enable
using System;
namespace Barotrauma
{
///
/// Implementation of Option type.
///
///
/// Credit Jlobblet
///
public abstract class Option
{
public static Option Some(T value) => Some.Create(value);
public static Option None() => None.Create();
public bool IsNone() => this is None;
public bool IsSome() => this is Some;
public bool TryUnwrap(out T outValue) => TryUnwrap(out outValue);
public bool TryUnwrap(out T1 outValue) where T1 : T
{
switch (this)
{
case Some { Value: T1 value }:
outValue = value;
return true;
default:
outValue = default!;
return false;
}
}
public Option Select(Func selector) =>
this switch
{
Some { Value: var value } => Option.Some(selector.Invoke(value)),
None _ => Option.None(),
_ => throw new ArgumentOutOfRangeException()
};
public abstract Option Fallback(Option fallback);
public abstract T Fallback(T fallback);
public abstract bool ValueEquals(T value);
public override bool Equals(object? obj)
=> obj switch
{
Some { Value: var value } => this is Some { Value: { } selfValue } && selfValue.Equals(value),
None _ => IsNone(),
T value => this is Some { Value: { } selfValue } && selfValue.Equals(value),
_ => false
};
public override int GetHashCode()
=> this is Some { Value: { } value } ? value.GetHashCode() : 0;
public static bool operator ==(Option a, Option b)
=> a.Equals(b);
public static bool operator !=(Option a, Option b)
=> !(a == b);
public abstract override string ToString();
public static implicit operator Option(Option.UnspecifiedNone _)
=> None();
}
public static class Option
{
public sealed class UnspecifiedNone
{
private UnspecifiedNone() { }
internal static readonly UnspecifiedNone Instance = new();
}
public static UnspecifiedNone None => UnspecifiedNone.Instance;
public static Option Some(T value) => Option.Some(value);
}
}