namespace Ghost.Core; public readonly struct Result { private readonly bool _isSuccess; private readonly string? _message; public readonly bool IsSuccess => _isSuccess; public readonly bool IsFailure => !_isSuccess; public readonly string? Message => _message; public Result(bool success, string? message = null) { _isSuccess = success; _message = message; } public static Result Success() { return new Result(true); } public static Result Failure(string? message = null) { return new Result(false, message); } public static Result Success(T value) { return Result.Success(value); } public static Result Failure(string? message = null) { return Result.Failure(message); } public static Result Create(T value, S status) where S : Enum { return new Result(value, status); } public static RefResult CreateRef(ref T value, S status) where S : Enum { return new RefResult(ref value, status); } public override string ToString() => IsSuccess ? "OK" : $"Error: {Message}"; public static implicit operator bool(Result result) => result.IsSuccess; } public readonly struct Result { private readonly bool _isSuccess; private readonly T _value; private readonly string? _message; public readonly bool IsSuccess => _isSuccess; public readonly bool IsFailure => !_isSuccess; public readonly T Value => _value; public readonly string? Message => _message; public Result(bool success, T value, string? message = null) { _isSuccess = success; _value = value; _message = message; } public static Result Success(T value) { return new Result(true, value); } public static Result Failure(string? message = null) { return new Result(false, default!, message); } public override string ToString() => IsSuccess ? $"OK: {Value}" : $"Error: {Message}"; public static implicit operator Result(T? data) => data is not null ? Success(data) : Failure(null); public static implicit operator Result(Result result) => result.IsSuccess ? Success(default!) : Failure(result.Message); public static implicit operator bool(Result result) => result.IsSuccess; } public enum ResultStatus : byte { Success, NotFound, InvalidArgument, InvalidState, InternalError, PermissionDenied, NotSupported, OutOfMemory, Timeout, Cancelled, UnknownError } public readonly struct Result where S : Enum { private readonly T _value; private readonly S _status; public T Value => _value; public S Status => _status; public Result(T value, S status) { _value = value; _status = status; } public static Result Create(T value, S status) { return new Result(value, status); } public override string ToString() => $"Value: {_value}, Status: {_status}"; } public readonly ref struct RefResult where S : Enum { private readonly ref T _value; private readonly S _status; public ref T Value => ref _value; public S Status => _status; public RefResult(ref T value, S status) { _value = ref value; _status = status; } public static RefResult Create(ref T value, S status) { return new RefResult(ref value, status); } public override string ToString() => $"Value: {_value}, Status: {_status}"; } public static class ResultExtensions { public static void ThrowIfFailed(this Result result) { if (!result.IsSuccess) { throw new InvalidOperationException($"Operation failed: {result.Message}"); } } public static T GetValueOrThrow(this Result result) { if (!result.IsSuccess) { throw new InvalidOperationException($"Operation failed: {result.Message}"); } return result.Value; } public static T? GetValueOrDefault(this Result result, T? defaultValue = default) { return result.IsSuccess ? result.Value : defaultValue; } public static T GetValueOrThrow(this Result result, S expect) where S : Enum { if (!EqualityComparer.Default.Equals(result.Status, expect)) { throw new InvalidOperationException($"Operation failed: expected status {expect}, but got {result.Status}"); } return result.Value; } public static T? GetValueOrDefault(this Result result, S expect, T? defaultValue = default) where S : Enum { return (result.Status?.Equals(expect) ?? false) ? defaultValue : result.Value; } public static Result OnSuccess(this Result result, Action action) { if (result.IsSuccess) { action(); } return result; } public static Result OnSuccess(this Result result, Action action) { if (result.IsSuccess) { action(result.Value); } return result; } public static Result OnFailed(this Result result, Action action) { if (result.IsFailure) { action(result.Message); } return result; } public static Result OnFailed(this Result result, Action action) { if (result.IsFailure) { action(result.Message); } return result; } }