diff --git a/Toolkit.Foundation/Error.cs b/Toolkit.Foundation/Error.cs index c12219a..cdbe68f 100644 --- a/Toolkit.Foundation/Error.cs +++ b/Toolkit.Foundation/Error.cs @@ -1,14 +1,12 @@ namespace Toolkit.Foundation; -public record Error(string Code, string Message) +public record Reason(string Code, string Message) { - public static readonly Error None = new(string.Empty, string.Empty); + public static readonly Reason None = new(string.Empty, string.Empty); - public static readonly Error Null = new("Error.NullValue", "The specified result value is null."); + public static readonly Reason Null = new("Error.NullValue", "The specified result value is null."); - public static readonly Error ConditionNotMet = new("Error.ConditionNotMet", "The specified condition was not met."); + public static readonly Reason ConditionNotMet = new("Error.ConditionNotMet", "The specified condition was not met."); - public static readonly Error Duplicated = new("Error.Duplicated", "The specified item already exists."); - - public static readonly Error Failure = new("Error.Failure", "The operation has failed."); + public static readonly Reason Failure = new("Error.Failure", "The operation has failed."); } diff --git a/Toolkit.Foundation/RequestEventArgs.cs b/Toolkit.Foundation/RequestEventArgs.cs index 0165c22..8a7879a 100644 --- a/Toolkit.Foundation/RequestEventArgs.cs +++ b/Toolkit.Foundation/RequestEventArgs.cs @@ -1,16 +1,18 @@ namespace Toolkit.Foundation; -public record RequestEventArgs +public record RequestEventArgs { - public TSender? Sender { get; } + public object? Sender { get; init; } - public RequestEventArgs(TSender sender) + public RequestEventArgs(object? sender = null) { Sender = sender; } +} - public RequestEventArgs() +public record RequestEventArgs : RequestEventArgs +{ + public RequestEventArgs(TSender sender) : base(sender) { - } -} \ No newline at end of file +} diff --git a/Toolkit.Foundation/Result.cs b/Toolkit.Foundation/Result.cs index d826867..678dcee 100644 --- a/Toolkit.Foundation/Result.cs +++ b/Toolkit.Foundation/Result.cs @@ -1,39 +1,53 @@ namespace Toolkit.Foundation; -public record Result : - Result +public record Result : Result { - private readonly TValue? value; + public TValue? Value { get; } - protected internal Result(TValue? value, bool isSuccess, Error error) - : base(isSuccess, error) => this.value = value; + public Result(TValue? value, bool isSuccess, Reason reason) + : base(isSuccess, reason) + { + Value = value; + } - public TValue? Value => - IsSuccess ? value! : default; - - public static implicit operator Result(TValue? value) => + public static implicit operator Result(TValue? value) => Create(value); + + public static implicit operator TValue?(Result result) => + result.IsSuccess ? result.Value : default; } -public record Result(bool IsSuccess, - Error Error) +public record Result { + public bool IsSuccess { get; init; } + public bool IsFailure => !IsSuccess; - public static Result Success() => new(true, Error.None); + public Reason Reason { get; init; } = Reason.None; - public static Result Success(TValue value) => - new(value, true, Error.None); + protected Result(bool isSuccess, Reason reason) + { + IsSuccess = isSuccess; + Reason = reason; + } - public static Result Failure(Error error) => - new(false, error); + public static Result Success() => new(true, Reason.None); - public static Result Failure(Error error) => - new(default, false, error); + public static Result Failure(Reason reason) => new(false, reason); - public static Result Create(bool condition) => - condition ? Success() : Failure(Error.ConditionNotMet); + public static Result Create(bool condition) => + condition ? Success() : Failure(Reason.ConditionNotMet); - public static Result Create(TValue? value) => - value is not null ? Success(value) : Failure(Error.Null); -} \ No newline at end of file + public static Result Success(TValue value) => + new(value, true, Reason.None); + + public static Result Failure(Reason reason, TValue? value = default) => + new(value, false, reason); + + public static Result Create(TValue? value) => + value is not null ? Success(value) : Failure(Reason.Null); + + public static Result Empty() => Failure(Reason.None); + + public static Result Empty() => Failure(Reason.None); +} diff --git a/Toolkit.Foundation/ResultExtensions.cs b/Toolkit.Foundation/ResultExtensions.cs new file mode 100644 index 0000000..af90b07 --- /dev/null +++ b/Toolkit.Foundation/ResultExtensions.cs @@ -0,0 +1,36 @@ +namespace Toolkit.Foundation; + +public static class ResultExtensions +{ + public static TResult Failure(this object? sender, + Reason reason) + where TResult : Result + { + if (typeof(TResult).IsGenericType && typeof(TResult).GetGenericTypeDefinition() == typeof(Result<>)) + { + object? value = sender is not null && typeof(TResult).GetGenericArguments()[0].IsAssignableFrom(sender.GetType()) + ? sender : Activator.CreateInstance(typeof(TResult).GetGenericArguments()[0].MakeNullable()); + + return (TResult)Activator.CreateInstance(typeof(TResult), value, false, reason)!; + } + + return (TResult)Activator.CreateInstance(typeof(TResult), false, reason)!; + } + + public static TResult Success(this object? sender) + where TResult : Result + { + if (typeof(TResult).IsGenericType && typeof(TResult).GetGenericTypeDefinition() == typeof(Result<>)) + { + object? value = sender is not null && typeof(TResult).GetGenericArguments()[0].IsAssignableFrom(sender.GetType()) + ? sender : Activator.CreateInstance(typeof(TResult).GetGenericArguments()[0].MakeNullable()); + + return (TResult)Activator.CreateInstance(typeof(TResult), value, true, Reason.None)!; + } + + return (TResult)Activator.CreateInstance(typeof(TResult), true, Reason.None)!; + } + + public static TResult Create(this object? sender, bool condition) + where TResult : Result => condition ? sender.Success() : sender.Failure(Reason.ConditionNotMet); +} diff --git a/Toolkit.Foundation/TypeExtensions.cs b/Toolkit.Foundation/TypeExtensions.cs new file mode 100644 index 0000000..917fe09 --- /dev/null +++ b/Toolkit.Foundation/TypeExtensions.cs @@ -0,0 +1,9 @@ +namespace Toolkit.Foundation; + +public static class TypeExtensions +{ + public static Type MakeNullable(this Type type) => + type.IsValueType && Nullable.GetUnderlyingType(type) == null + ? typeof(Nullable<>).MakeGenericType(type) + : type; +}