104 lines
2.6 KiB
C#
104 lines
2.6 KiB
C#
|
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;
|
||
|
}
|
||
|
}
|