using System;
using UnityEngine.Rendering.Universal;
namespace KitsuneCafe.Sys
{
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})";
}
}
}