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