using System; namespace Escape_Room_Engine.Engine.Scripts.Utilities { /// /// Optional type with a subset of the functionality of the one described in the Rust documentation at https://doc.rust-lang.org/std/option/enum.Option.html. /// public interface IOption { public bool IsSome(); public bool IsNone(); public T Expect(string message); public T Unwrap(); public T UnwrapOr(T def); public T UnwrapOrElse(Func f); public IOption And(IOption other); public IOption Or(IOption other); public bool Contains(T value); public T Match(Func some, Func none); public void Match(Action some, Action none); public void Match(Action some); public void Match(Action none); } public class Some : IOption { private readonly T _value; private Some(T value) => _value = value; public bool IsSome() => true; public bool IsNone() => false; public T Expect(string message) => _value; public T Unwrap() => _value; public T UnwrapOr(T def) => _value; public T UnwrapOrElse(Func f) => _value; public IOption And(IOption other) => other; public IOption Or(IOption other) => this; public bool Contains(T value) => _value.Equals(value); public T Match(Func some, Func none) => some(_value); public void Match(Action some, Action none) => some(_value); public void Match(Action some) => some(_value); public void Match(Action none) {} public static IOption Of(T value) => new Some(value); } public class None : IOption { public bool IsSome() => false; public bool IsNone() => true; public T Expect(string message) => throw new Exception(message); public T Unwrap() => throw new Exception("Tried to unwrap None."); public T UnwrapOr(T def) => def; public T UnwrapOrElse(Func f) => f(); public IOption And(IOption other) => this; public IOption Or(IOption other) => other; public bool Contains(T value) => false; public T Match(Func some, Func none) => none(); public void Match(Action some, Action none) => none(); public void Match(Action some) {} public void Match(Action none) => none(); public static IOption New() => new None(); } }