Introduce Result<T,E>, an either monad
This commit is contained in:
parent
fc77a752b4
commit
3728ae747f
|
@ -0,0 +1,104 @@
|
||||||
|
namespace InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: discriminated union
|
||||||
|
public abstract record Result<T>
|
||||||
|
{
|
||||||
|
public sealed record Success(T Value) : Result<T>;
|
||||||
|
public sealed record Failure(String Error) : Result<T>;
|
||||||
|
|
||||||
|
public Boolean IsError => this is Failure;
|
||||||
|
public Boolean IsOk => this is Success;
|
||||||
|
|
||||||
|
public static implicit operator Result<T>(T t) => new Success(t);
|
||||||
|
public static implicit operator Result<T>(String e) => new Failure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract record Result<T, E>
|
||||||
|
{
|
||||||
|
public sealed record Success(T Value) : Result<T, E>;
|
||||||
|
public sealed record Failure(E Error) : Result<T, E>;
|
||||||
|
|
||||||
|
public Boolean IsError => this is Failure;
|
||||||
|
public Boolean IsOk => this is Success;
|
||||||
|
|
||||||
|
public static implicit operator Result<T, E>(T t) => new Success(t);
|
||||||
|
public static implicit operator Result<T, E>(E e) => new Failure(e);
|
||||||
|
|
||||||
|
public R Map<R>(Func<T, R> onSuccess, Func<E, R> onFailure) => this switch
|
||||||
|
{
|
||||||
|
Success s => onSuccess(s.Value),
|
||||||
|
Failure f => onFailure(f.Error),
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
};
|
||||||
|
|
||||||
|
public Result<R, E> OnSuccess<R>(Func<T, R> onOk) => this switch
|
||||||
|
{
|
||||||
|
Success s => onOk(s.Value),
|
||||||
|
Failure f => f.Error,
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
};
|
||||||
|
|
||||||
|
public Result<T, R> OnFailure<R>(Func<E, R> onError) => this switch
|
||||||
|
{
|
||||||
|
Success s => s.Value,
|
||||||
|
Failure f => onError(f.Error),
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Result
|
||||||
|
{
|
||||||
|
public static Result<T, Exception> Try<T>(Func<T> func)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return func();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String? GetError<T>(this Result<T> r)
|
||||||
|
{
|
||||||
|
return r is Result<T>.Failure err
|
||||||
|
? err.Error
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ResultClass
|
||||||
|
{
|
||||||
|
public static T? GetValue<T>(this Result<T> r) where T : class
|
||||||
|
{
|
||||||
|
return r is Result<T>.Success ok
|
||||||
|
? ok.Value
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static E? GetError<T, E>(this Result<T, E> r) where E : class
|
||||||
|
{
|
||||||
|
return r is Result<T, E>.Failure err
|
||||||
|
? err.Error
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ResultStruct
|
||||||
|
{
|
||||||
|
public static T? GetValue<T>(this Result<T> r) where T : struct
|
||||||
|
{
|
||||||
|
return r is Result<T>.Success ok
|
||||||
|
? ok.Value
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static E? GetError<T, E>(this Result<T, E> r) where E : struct
|
||||||
|
{
|
||||||
|
return r is Result<T,E>.Failure err
|
||||||
|
? err.Error
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
namespace InnovEnergy.Lib.Utils.WIP;
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: discriminated union
|
|
||||||
public abstract record Result
|
|
||||||
{
|
|
||||||
public sealed record Ok(Object Result) : Result;
|
|
||||||
public sealed record Error(String Message) : Result;
|
|
||||||
}
|
|
Loading…
Reference in New Issue