// 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 { private readonly Exception? _exception; private readonly bool _isSuccess; /// /// 私有构造函数,用于创建 Result 实例 /// /// 是否为成功状态 /// 失败时的异常信息 private Result(bool isSuccess, Exception? exception) { _isSuccess = isSuccess; _exception = exception; } /// /// 判断结果是否为成功状态 /// [Pure] public bool IsSuccess => _isSuccess; /// /// 判断结果是否为失败状态 /// [Pure] public bool IsFailure => !_isSuccess; /// /// 获取失败时的异常信息,若为成功状态则抛出 InvalidOperationException /// [Pure] public Exception Error => IsFailure ? _exception! : throw new InvalidOperationException("Cannot access Error on a successful Result."); /// /// 创建成功结果 /// /// 成功结果 [Pure] public static Result Success() => new(true, null); /// /// 创建失败结果 /// /// 失败的异常 /// 失败结果 [Pure] public static Result Failure(Exception ex) { ArgumentNullException.ThrowIfNull(ex); return new(false, ex); } /// /// 根据错误消息创建失败结果 /// /// 错误消息 /// 失败结果 [Pure] public static Result Failure(string message) { ArgumentException.ThrowIfNullOrWhiteSpace(message); return new(false, new Exception(message)); } /// /// 根据成功或失败状态分别执行不同的处理逻辑 /// /// 返回值类型 /// 成功时执行的函数 /// 失败时执行的函数 /// 处理后的结果 public R Match(Func onSuccess, Func onFailure) => IsSuccess ? onSuccess() : onFailure(_exception!); /// /// 将当前无值的 Result 提升为带值的 Result /// /// 值的类型 /// 成功时关联的值 /// 带值的 Result [Pure] public Result ToResult(A value) => IsSuccess ? Result.Success(value) : Result.Failure(_exception!); /// /// 判断当前 Result 是否与另一个 Result 相等 /// /// 另一个 Result /// 若相等返回 true,否则返回 false [Pure] public bool Equals(Result other) { // 比较状态和异常信息 return _isSuccess == other._isSuccess && (!IsFailure || (_exception?.GetType() == other._exception?.GetType() && _exception?.Message == other._exception?.Message)); } /// /// 判断当前对象是否与另一个对象相等 /// /// 另一个对象 /// 若相等返回 true,否则返回 false [Pure] public override bool Equals(object? obj) => obj is Result other && Equals(other); /// /// 获取当前 Result 的哈希码 /// /// 哈希码 [Pure] public override int GetHashCode() { // 根据状态和异常信息生成哈希码 return IsSuccess ? HashCode.Combine(true) : HashCode.Combine(false, _exception?.GetType(), _exception?.Message); } /// /// 判断两个 Result 是否相等 /// /// 第一个 Result /// 第二个 Result /// 若相等返回 true,否则返回 false [Pure] public static bool operator ==(Result a, Result b) => a.Equals(b); /// /// 判断两个 Result 是否不相等 /// /// 第一个 Result /// 第二个 Result /// 若不相等返回 true,否则返回 false [Pure] public static bool operator !=(Result a, Result b) => !a.Equals(b); /// /// 返回当前 Result 的字符串表示 /// /// Result 的字符串表示 [Pure] public override string ToString() => IsSuccess ? "Success" : $"Fail({_exception?.Message ?? "Unknown"})"; }