Barotrauma Client Doc
Option.cs
1 #nullable enable
2 using System;
3 using System.Diagnostics.CodeAnalysis;
4 
5 namespace Barotrauma
6 {
7  public readonly struct Option<T> where T : notnull
8  {
9  private readonly bool hasValue;
10  private readonly T? value;
11 
12  private Option(bool hasValue, T? value)
13  {
14  this.hasValue = hasValue;
15  this.value = value;
16  }
17 
18  public bool IsSome() => hasValue;
19  public bool IsNone() => !IsSome();
20 
21  public bool TryUnwrap<T1>([NotNullWhen(returnValue: true)] out T1? outValue) where T1 : T
22  {
23  bool hasValueOfGivenType = false;
24  outValue = default;
25 
26  if (hasValue && value is T1 t1)
27  {
28  hasValueOfGivenType = true;
29  outValue = t1;
30  }
31 
32  return hasValueOfGivenType;
33  }
34 
35  public bool TryUnwrap([NotNullWhen(returnValue: true)] out T? outValue)
36  => TryUnwrap<T>(out outValue);
37 
38  public Option<TType> Select<TType>(Func<T, TType> selector) where TType : notnull
39  => TryUnwrap(out T? selfValue) ? Option.Some(selector(selfValue)) : Option.None;
40 
41  public Option<TType> Bind<TType>(Func<T, Option<TType>> binder) where TType : notnull
42  => TryUnwrap(out T? selfValue) ? binder(selfValue) : Option.None;
43 
44  public T Match(Func<T, T> some, Func<T> none)
45  => TryUnwrap(out T? selfValue) ? some(selfValue) : none();
46 
47  public void Match(Action<T> some, Action none)
48  {
49  if (TryUnwrap(out T? selfValue))
50  {
51  some(selfValue);
52  return;
53  }
54  none();
55  }
56 
57  public T Fallback(T fallback)
58  => TryUnwrap(out var v) ? v : fallback;
59 
60  public Option<T> Fallback(Option<T> fallback)
61  => IsSome() ? this : fallback;
62 
63  public static Option<T> Some(T value)
64  => typeof(T) switch
65  {
66  var t when t == typeof(bool)
67  => throw new Exception("Option type rejects booleans"),
68  {IsConstructedGenericType: true} t when t.GetGenericTypeDefinition() == typeof(Option<>)
69  => throw new Exception("Option type rejects nested Option"),
70  {IsConstructedGenericType: true} t when t.GetGenericTypeDefinition() == typeof(Nullable<>)
71  => throw new Exception("Option type rejects Nullable"),
72  _
73  => new Option<T>(hasValue: true, value: value ?? throw new Exception("Option type rejects null"))
74  };
75 
76  public override bool Equals(object? obj)
77  => obj switch
78  {
79  Option<T> otherOption when otherOption.IsNone()
80  => IsNone(),
81  Option<T> otherOption when otherOption.TryUnwrap(out var otherValue)
82  => ValueEquals(otherValue),
83  T otherValue
84  => ValueEquals(otherValue),
85  _
86  => false
87  };
88 
89  public bool ValueEquals(T otherValue)
90  => TryUnwrap(out T? selfValue) && selfValue.Equals(otherValue);
91 
92  public override int GetHashCode()
93  => TryUnwrap(out T? selfValue) ? selfValue.GetHashCode() : 0;
94 
95  public static bool operator ==(Option<T> a, Option<T> b)
96  => a.Equals(b);
97 
98  public static bool operator !=(Option<T> a, Option<T> b)
99  => !(a == b);
100 
101  public static Option<T> None()
102  => default;
103 
104  public static implicit operator Option<T>(in Option.UnspecifiedNone _)
105  => None();
106 
107  public override string ToString()
108  => TryUnwrap(out var selfValue)
109  ? $"Some<{typeof(T).Name}>({selfValue})"
110  : $"None<{typeof(T).Name}>";
111  }
112 
113  public static class Option
114  {
115  public static Option<T> Some<T>(T value) where T : notnull
116  => Option<T>.Some(value);
117 
118  public static UnspecifiedNone None
119  => default;
120 
121  public readonly ref struct UnspecifiedNone
122  {
123  }
124  }
125 }
Option< T > Fallback(Option< T > fallback)
void Match(Action< T > some, Action none)
Definition: Option.cs:47
override bool Equals(object? obj)
bool ValueEquals(T otherValue)
T Match(Func< T, T > some, Func< T > none)
override string ToString()
bool TryUnwrap< T1 >([NotNullWhen(returnValue:true)] out T1? outValue)
Definition: Option.cs:21
bool TryUnwrap([NotNullWhen(returnValue:true)] out T? outValue)
static Option< T > Some< T >(T value)
static bool operator!=(Option< T > a, Option< T > b)
static Option< T > None()
static Option< T > Some(T value)
override int GetHashCode()
T Fallback(T fallback)
static bool operator==(Option< T > a, Option< T > b)
static UnspecifiedNone None
Definition: Option.cs:119
Option< TType > Bind< TType >(Func< T, Option< TType >> binder)
Option< TType > Select< TType >(Func< T, TType > selector)