51 lines
1.5 KiB
C#
51 lines
1.5 KiB
C#
namespace Fleet.Core;
|
|
|
|
public record FleetError(ErrorCode Code, string Message)
|
|
{
|
|
public override string ToString() => $"{Code}: {Message}";
|
|
}
|
|
|
|
/// <summary>预期内的失败用结果表示,不抛异常。</summary>
|
|
public readonly struct Result<T>
|
|
{
|
|
private readonly T? _value;
|
|
private readonly FleetError? _error;
|
|
|
|
private Result(T? value, FleetError? error)
|
|
{
|
|
_value = value;
|
|
_error = error;
|
|
}
|
|
|
|
public bool IsSuccess => _error is null;
|
|
|
|
public T Value => _error is null ? _value! : throw new InvalidOperationException(_error.ToString());
|
|
|
|
public FleetError Error => _error ?? throw new InvalidOperationException("Result is successful.");
|
|
|
|
public static Result<T> Ok(T value) => new(value, null);
|
|
|
|
public static Result<T> Fail(FleetError error) => new(default, error);
|
|
|
|
public static Result<T> Fail(ErrorCode code, string message) => new(default, new FleetError(code, message));
|
|
|
|
public bool TryGet(out T value, out FleetError error)
|
|
{
|
|
value = _value!;
|
|
error = _error!;
|
|
return _error is null;
|
|
}
|
|
|
|
public Result<TOut> Map<TOut>(Func<T, TOut> map) =>
|
|
_error is null ? Result<TOut>.Ok(map(_value!)) : Result<TOut>.Fail(_error);
|
|
|
|
public static implicit operator Result<T>(FleetError error) => Fail(error);
|
|
}
|
|
|
|
public static class Result
|
|
{
|
|
public static Result<T> Ok<T>(T value) => Result<T>.Ok(value);
|
|
|
|
public static Result<T> Fail<T>(ErrorCode code, string message) => Result<T>.Fail(code, message);
|
|
}
|