// 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; // ------------------------------------------------------------------ 状态枚举 /// /// 表示 Result 结构体的内部状态 /// private enum ResultState { /// /// 未初始化状态,表示 Result 尚未被赋值 /// 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; /// /// 获取内部异常: /// - 若为 Failure 状态,则返回内部异常 /// - 若为 Bottom 状态,则返回带有 "Result is in Bottom state." 消息的 InvalidOperationException /// - 若为 Success 状态,则返回带有 "Cannot access Exception on a successful Result." 消息的 InvalidOperationException /// [Pure] public Exception Exception => _exception ?? (IsBottom ? new InvalidOperationException("Result is in Bottom state.") : new InvalidOperationException( "Cannot access Exception on a successful Result.")); // ------------------------------------------------------------------ 取值 /// /// 若成功则返回值,若失败则返回默认值 /// /// 失败时返回的默认值 /// 成功时的值或默认值 [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) { ArgumentNullException.ThrowIfNull(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)" }; }