Innovenergy_trunk/csharp/Lib/Utils/Result.cs

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;
}
}