// Copyright (c) 2025 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Diagnostics.Contracts;
namespace GFramework.Core.Functional;
///
/// 表示一个操作的结果,可能是成功值或异常
///
public readonly struct Result : IEquatable>, IComparable>
{
private readonly A? _value;
private readonly Exception? _exception;
// ------------------------------------------------------------------ 状态枚举
///
/// 结果状态枚举,表示结果的不同状态
/// 排序: Bottom < Faulted < Success
///
private enum ResultState : byte
{
Bottom,
Faulted,
Success
}
private readonly ResultState _state;
// ------------------------------------------------------------------ 静态默认值
///
/// 表示未初始化的 Bottom 状态
///
public static readonly Result Bottom = default;
// ------------------------------------------------------------------ 构造器
///
/// 构造成功结果
///
/// 成功的值
public Result(A value)
{
_state = ResultState.Success;
_value = value;
_exception = null;
}
///
/// 构造失败结果
///
/// 失败的异常
public Result(Exception exception)
{
_state = ResultState.Faulted;
_exception = exception ?? throw new ArgumentNullException(nameof(exception));
_value = default;
}
// ------------------------------------------------------------------ 隐式转换
///
/// 隐式将值转换为成功结果
///
/// 要转换的值
/// 成功结果
[Pure]
public static implicit operator Result(A value) => new(value);
// ------------------------------------------------------------------ 状态属性
///
/// 判断结果是否为成功状态
///
[Pure]
public bool IsSuccess => _state == ResultState.Success;
///
/// 判断结果是否为失败状态
///
[Pure]
public bool IsFaulted => _state == ResultState.Faulted;
///
/// 判断结果是否为未初始化的 Bottom 状态
///
[Pure]
public bool IsBottom => _state == ResultState.Bottom;
///
/// 获取内部异常,若为 Bottom 状态则抛出 InvalidOperationException
///
[Pure]
public Exception Exception => _exception
?? new InvalidOperationException("Result is in Bottom state.");
// ------------------------------------------------------------------ 取值
///
/// 若成功则返回值,若失败则返回默认值
///
/// 失败时返回的默认值
/// 成功时的值或默认值
[Pure]
public A IfFail(A defaultValue) => IsSuccess ? _value! : defaultValue;
///
/// 若成功则返回值,若失败则通过委托处理异常
///
/// 处理异常的委托
/// 成功时的值或委托处理后的结果
[Pure]
public A IfFail(Func f) => IsSuccess ? _value! : f(Exception);
///
/// 若失败则执行副作用
///
/// 处理异常的副作用委托
public void IfFail(Action f)
{
if (IsFaulted) f(Exception);
}
///
/// 若成功则执行副作用
///
/// 处理成功值的副作用委托
public void IfSucc(Action f)
{
if (IsSuccess) f(_value!);
}
// ------------------------------------------------------------------ 变换
///
/// 成功时映射值,失败时透传异常
///
/// 映射后的类型
/// 映射函数
/// 映射后的结果
[Pure]
public Result Map(Func f)
{
ArgumentNullException.ThrowIfNull(f);
return IsSuccess ? new Result(f(_value!)) : new Result(Exception);
}
///
/// 成功时绑定到新 Result,失败时透传异常
///
/// 绑定后的类型
/// 绑定函数
/// 绑定后的结果
[Pure]
public Result Bind(Func> binder)
{
ArgumentNullException.ThrowIfNull(binder);
return IsSuccess ? binder(_value!) : new Result(Exception);
}
///
/// 异步映射
///
/// 映射后的类型
/// 异步映射函数
/// 异步映射后的结果
[Pure]
public async Task> MapAsync(Func> f)
{
ArgumentNullException.ThrowIfNull(f);
if (!IsSuccess) return new Result(Exception);
try
{
return new Result(await f(_value!));
}
catch (Exception ex)
{
return new Result(ex);
}
}
// ------------------------------------------------------------------ 模式匹配
///
/// 对成功/失败两种情况分别处理并返回值
///
/// 返回值类型
/// 处理成功值的函数
/// 处理异常的函数
/// 处理后的结果
[Pure]
public R Match(Func succ, Func fail) =>
IsSuccess ? succ(_value!) : fail(Exception);
///
/// 对成功/失败两种情况分别执行副作用
///
/// 处理成功值的副作用委托
/// 处理异常的副作用委托
public void Match(Action succ, Action fail)
{
if (IsSuccess) succ(_value!);
else fail(Exception);
}
// ------------------------------------------------------------------ 静态工厂(语义更清晰)
///
/// 创建成功结果
///
/// 成功的值
/// 成功结果
[Pure]
public static Result Succeed(A value) => new(value);
///
/// 创建成功结果(别名)
///
/// 成功的值
/// 成功结果
[Pure]
public static Result Success(A value) => new(value);
///
/// 创建失败结果
///
/// 失败的异常
/// 失败结果
[Pure]
public static Result Fail(Exception ex) => new(ex);
///
/// 创建失败结果(别名)
///
/// 失败的异常
/// 失败结果
[Pure]
public static Result Failure(Exception ex) => new(ex);
///
/// 根据错误消息创建失败结果
///
/// 错误消息
/// 失败结果
[Pure]
public static Result Failure(string message) => new(new Exception(message));
///
/// 安全执行委托,自动捕获异常
///
/// 要执行的委托
/// 执行结果
public static Result Try(Func f)
{
try
{
return new Result(f());
}
catch (Exception ex)
{
return new Result(ex);
}
}
// ------------------------------------------------------------------ 相等 / 比较
///
/// 判断两个结果是否相等
///
/// 另一个结果
/// 若相等返回 true,否则返回 false
[Pure]
public bool Equals(Result other)
{
if (_state != other._state) return false;
if (IsSuccess) return EqualityComparer.Default.Equals(_value, other._value);
if (IsFaulted)
return Exception.GetType() == other.Exception.GetType()
&& Exception.Message == other.Exception.Message;
return true; // both Bottom
}
///
/// 判断对象是否与当前结果相等
///
/// 要比较的对象
/// 若相等返回 true,否则返回 false
[Pure]
public override bool Equals(object? obj) => obj is Result other && Equals(other);
///
/// 获取结果的哈希码
///
/// 哈希码
[Pure]
public override int GetHashCode() => IsSuccess
? HashCode.Combine(0, _value)
: HashCode.Combine(1, Exception.GetType(), Exception.Message);
///
/// 比较两个结果的大小
///
/// 另一个结果
/// 比较结果
[Pure]
public int CompareTo(Result other)
{
// Bottom < Faulted < Success
if (_state != other._state) return _state.CompareTo(other._state);
if (!IsSuccess) return 0;
try
{
return Comparer.Default.Compare(_value, other._value);
}
catch (ArgumentException)
{
// 类型不可比较时返回 0
return 0;
}
}
///
/// 判断两个结果是否相等
///
/// 第一个结果
/// 第二个结果
/// 若相等返回 true,否则返回 false
[Pure]
public static bool operator ==(Result a, Result b) => a.Equals(b);
///
/// 判断两个结果是否不相等
///
/// 第一个结果
/// 第二个结果
/// 若不相等返回 true,否则返回 false
[Pure]
public static bool operator !=(Result a, Result b) => !a.Equals(b);
///
/// 判断第一个结果是否小于第二个结果
///
/// 第一个结果
/// 第二个结果
/// 若小于返回 true,否则返回 false
[Pure]
public static bool operator <(Result a, Result b) => a.CompareTo(b) < 0;
///
/// 判断第一个结果是否小于等于第二个结果
///
/// 第一个结果
/// 第二个结果
/// 若小于等于返回 true,否则返回 false
[Pure]
public static bool operator <=(Result a, Result b) => a.CompareTo(b) <= 0;
///
/// 判断第一个结果是否大于第二个结果
///
/// 第一个结果
/// 第二个结果
/// 若大于返回 true,否则返回 false
[Pure]
public static bool operator >(Result a, Result b) => a.CompareTo(b) > 0;
///
/// 判断第一个结果是否大于等于第二个结果
///
/// 第一个结果
/// 第二个结果
/// 若大于等于返回 true,否则返回 false
[Pure]
public static bool operator >=(Result a, Result b) => a.CompareTo(b) >= 0;
// ------------------------------------------------------------------ 调试
///
/// 返回结果的字符串表示
///
/// 结果的字符串表示
[Pure]
public override string ToString() => _state switch
{
ResultState.Success => _value?.ToString() ?? "(null)",
ResultState.Faulted => $"Fail({Exception.Message})",
_ => "(Bottom)"
};
}