using System; using UnityEngine.Rendering.Universal; namespace KitsuneCafe.System { public static class Result { /// /// Creates a successful Result with the specified value. /// Type inference for TError often occurs from the assignment context. /// public static IResult Ok(TValue value) { return new Ok(value); } /// /// Creates an erroneous Result with the specified error. /// Type inference for TValue often occurs from the assignment context. /// public static IResult Err(TError error) { return new Err(error); } } public interface IResult { public abstract bool IsOk { get; } public static IResult Ok(TValue value) => new Ok(value); public static IResult Err(TError error) => new Err(error); public abstract TValue Unwrap(); public abstract TError UnwrapErr(); public abstract IResult SelectMany(Func> func); public abstract IResult Select(Func func); public abstract IResult SelectErr(Func func); public abstract IResult Where(Func predicate); public abstract TResult Match(Func okFunc, Func errFunc); public abstract TValue UnwrapOrDefault(TValue defaultValue = default); public abstract TValue UnwrapOrElse(Func func); public virtual IResult Do(Action func) { if (IsOk) { func(Unwrap()); } return this; } public virtual IResult DoIfErr(Action func) { if (!IsOk) { func(UnwrapErr()); } return this; } } public readonly struct Ok : IResult { private readonly TValue value; public readonly bool IsOk => true; internal Ok(TValue value) { this.value = value; } public void Deconstruct(out TValue value) { value = this.value; } public IResult SelectMany(Func> func) { return func(value); } public TValue Unwrap() { return value; } public TError UnwrapErr() { throw new InvalidOperationException("Attempted to UnwrapErr an Ok"); } public IResult Select(Func func) { return IResult.Ok(func(value)); } public IResult SelectErr(Func func) { return IResult.Ok(value); } public IResult Where(Func predicate) { if (predicate(value)) { return this; } return IResult.Err(default); } public TResult Match(Func okFunc, Func errFunc) { return okFunc(value); } public TValue UnwrapOrDefault(TValue defaultValue = default) { return value; } public TValue UnwrapOrElse(Func func) { return value; } public override bool Equals(object obj) { return obj is Ok other && Equals(other); } public override int GetHashCode() { return HashCode.Combine(value); } public override string ToString() { return $"Ok({value})"; } } public readonly struct Err : IResult { private readonly TError error; public readonly bool IsOk => false; internal Err(TError error) { this.error = error; } public void Deconstruct(out TError error) { error = this.error; } public IResult SelectMany(Func> func) { return IResult.Err(error); } public TValue Unwrap() { throw new InvalidOperationException("Attempted to unwrap value of an Err."); } public TError UnwrapErr() { return error; } public IResult Select(Func func) { return IResult.Err(error); } public IResult SelectErr(Func func) { return IResult.Err(func(error)); } public IResult Where(Func predicate) { return IResult.Err(error); } public TResult Match(Func okFunc, Func errFunc) { return errFunc(error); } public TValue UnwrapOrDefault(TValue defaultValue = default) { return defaultValue; } public TValue UnwrapOrElse(Func func) { return func(); } public override bool Equals(object obj) { return obj is Err other && Equals(other); } public override int GetHashCode() { return HashCode.Combine(error); } public override string ToString() { return $"Err({error})"; } } }