diff --git a/src/Here/Here.csproj b/src/Here/Here.csproj index b62e65e..7f88ea0 100644 --- a/src/Here/Here.csproj +++ b/src/Here/Here.csproj @@ -22,14 +22,17 @@ Supported platforms: Alexandre Rabérin true Here - ➟ Release 0.2.0 -- For Maybe: - - Little optimizations - - New IfOr and ElseOr extensions. - - Easy conversions between numeric Maybe (ToInt(), ToLong(), ToDouble(), etc.) - - Conversion from numeric Maybe to Maybe<bool>. - - Try Get Value for dictionaries supports null key queries. - - Try Get Value for dictionary<TKey, object> supports value cast to an expected type. + ➟ Release 0.3.0 +- General: + - Add missing JetBrains annotations. + +- For Maybes: + - Add explicit and implicit converters to Result/Result<T>/CustomResult<T, TError>/Result<T, TError>. + +- For Results: + - Result can now always embed an Exception (for Warning and Failure). + - Add scopes to safely return a Result of any type. + - Add explicit and implicit converters to Maybe<T>. Here Functional C# Maybe Monad Result https://opensource.org/licenses/MIT https://github.com/KeRNeLith/Here diff --git a/src/Here/Maybe/README.md b/src/Here/Maybe/README.md index 9bd4417..acc2412 100644 --- a/src/Here/Maybe/README.md +++ b/src/Here/Maybe/README.md @@ -236,4 +236,24 @@ Maybe maybeInt = maybeDouble.ToInt(); // 42 // As a consequence you can chain calls like this: string myString = "51.52"; Maybe maybeDouble = myString.TryParseInt().ToDouble(); // 51 +``` + +### Bridge to Result + +It is possible to convert a `Maybe` to a `Result`, `Result`, `CustomResult` or `Result`. + +For the first two conversions, both also support implicit conversion. + +```csharp +var maybeInt = Maybe.Some(42); + +Result result = maybeInt.ToResult(); // Explicit => Result.OK +Result result = maybeInt; // Implicit => Result.OK + + +var emptyMaybeInt = Maybe.None; + +Result result = emptyMaybeInt.ToResult(); // Explicit => Result.Fail +Result result = emptyMaybeInt.ToResult("Custom failure message"); // Explicit => Result.Fail +Result result = emptyMaybeInt; // Implicit => Result.Fail ``` \ No newline at end of file diff --git a/src/Here/Result/README.md b/src/Here/Result/README.md index fb82c2c..1ce3a28 100644 --- a/src/Here/Result/README.md +++ b/src/Here/Result/README.md @@ -45,6 +45,7 @@ See below for some examples: Result simpleResult = Result.Ok(); simpleResult = Result.Warn("Your Warning message."); simpleResult = Result.Fail("Your ERROR message."); +simpleResult = Result.Fail("Your ERROR message.", new Exception("Embedded exception")); // Example with an embedded exception // Result with value Result resultValue = Result.Ok(42); @@ -105,4 +106,76 @@ So the only to have a failed result is obviously to use the `Fail` construction, The necessity to have a message for warnings and errors is motivated by the need to force the developer of a treatment to explain error cases. -Then you have `IResult` and `IResultError` that respectively provide a `Value` and a custom `Error`. \ No newline at end of file +Then you have `IResult` and `IResultError` that respectively provide a `Value` and a custom `Error`. + +### Safe Scopes + +If you want to run code that should return a Result safely, you can use Result scopes to do this. + +There is at least one per Result type. Following is an example with the scope for `Result`. + +```csharp +// Example 1 +public Result MyFunction() +{ + return ResultScope.SafeResult(() => + { + // ... + // Your code + + return Result.Ok(); + }); +} + +// The call will give +var result = MyFunction(); // Result.Ok() + +// Example 2 +public Result MyFunctionRaiseException() +{ + return ResultScope.SafeResult(() => + { + // ... + // Your code that trigger an exception + + return Result.Ok(); + }); +} + +// The call will give +var result = MyFunctionRaiseException(); // Result.Fail() + +// The scope catch exception and produce a Result that embed the thrown exception. +// So you can keep focus on your code rather than exception that it can trigger. +``` + +### Bridge to Maybe + +It is possible to convert a `Result`, `Result`, `CustomResult` or `Result` to a `Maybe`. + +Conversions from a `Result` or a `CustomResult` give a `Maybe`, the other give a `Maybe`. +Each conversion can be done implicitly too. + +```csharp +// Result without value +Result resultOK = Result.Ok(); + +Maybe maybeBool = resultOK.ToMaybe(); // Explicit => Maybe.Some(true) +Maybe maybeBool = resultOK; // Implicit => Maybe.Some(true) + +Result resultFail = Result.Fail("Failure"); + +Maybe maybeBool = resultFail.ToMaybe(); // Explicit => Maybe.Some(false) +Maybe maybeBool = resultFail; // Implicit => Maybe.Some(false) + +// Result with value +Result resultOK = Result.Ok(12); + +Maybe maybeBool = resultOK.ToMaybe(); // Explicit => Maybe.Some(12) +Maybe maybeBool = resultOK; // Implicit => Maybe.Some(12) + +Result resultFail = Result.Fail("Failure"); + +Maybe maybeBool = resultFail.ToMaybe(); // Explicit => Maybe.None +Maybe maybeBool = resultFail; // Implicit => Maybe.None +``` \ No newline at end of file diff --git a/src/Here/Result/ResultScopes.cs b/src/Here/Result/ResultScopes.cs index 802ffac..de6454e 100644 --- a/src/Here/Result/ResultScopes.cs +++ b/src/Here/Result/ResultScopes.cs @@ -91,7 +91,7 @@ public static CustomResult SafeCustomResult([NotNull, InstantHan /// Run the given in a safe scope that always return a . /// /// Function to call. - /// Function to create a custom error objec in case an exception is thrown. + /// Function to create a custom error object in case an exception is thrown. /// A . [PublicAPI] public static CustomResult SafeCustomResult([NotNull, InstantHandle] Func> action, [NotNull] Func errorFactory) @@ -135,7 +135,7 @@ public static Result SafeValueCustomResult([NotNull, Insta /// Run the given in a safe scope that always return a . /// /// Function to call. - /// Function to create a custom error objec in case an exception is thrown. + /// Function to create a custom error object in case an exception is thrown. /// A . [PublicAPI] public static Result SafeValueCustomResult([NotNull, InstantHandle] Func> action, [NotNull] Func errorFactory)