From a07f12e23b07fc6aac1003ea4b3743a1c9ca5db1 Mon Sep 17 00:00:00 2001 From: Rick Drizin Date: Sat, 3 Aug 2024 16:10:57 -0400 Subject: [PATCH] ResultOrErrors deconstruct: Result now has a new deconstruct (golang-style style): `Deconstruct(out TValue value, out List errors)` Returning isSuccess and isFailed were redundant since we can infer success/failure from non-null values in `TValue value` and `List errors`. ResultBase still has `Deconstruct(out bool isSuccess, out bool isFailed)`, so non-generic Results (without TValue) can still use that isSuccess/isFailed deconstruction, but the breaking change is that someone using Result can't use that bool/bool deconstruct anymore. --- .../ResultWithValueTests.cs | 35 +++++++++++++++---- src/FluentResults/Results/Result.cs | 11 ++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/FluentResults.Test/ResultWithValueTests.cs b/src/FluentResults.Test/ResultWithValueTests.cs index 803f016..adae038 100644 --- a/src/FluentResults.Test/ResultWithValueTests.cs +++ b/src/FluentResults.Test/ResultWithValueTests.cs @@ -998,21 +998,21 @@ public void Implicit_conversion_Result_Value_is_converted_to_Result_object_with_ } [Fact] - public void Can_deconstruct_generic_Ok_to_isSuccess_and_isFailed() + public void Can_deconstruct_generic_Ok_to_isSuccess_and_errors() { - var (isSuccess, isFailed) = Result.Ok(true); + var (isSuccess, errors) = Result.Ok(true); isSuccess.Should().Be(true); - isFailed.Should().Be(false); + errors.Should().BeNull(); } [Fact] - public void Can_deconstruct_generic_Fail_to_isSuccess_and_isFailed() + public void Can_deconstruct_generic_Fail_to_isSuccess_and_errors() { - var (isSuccess, isFailed) = Result.Fail("fail"); + var (isSuccess, errors) = Result.Fail("fail"); isSuccess.Should().Be(false); - isFailed.Should().Be(true); + errors.Should().NotBeNullOrEmpty(); } [Fact] @@ -1035,6 +1035,29 @@ public void Can_deconstruct_generic_Fail_to_isSuccess_and_isFailed_and_value() value.Should().Be(default); } + [Fact] + public void Can_deconstruct_generic_Ok_to_value_with_errors() + { + var (value, errors) = Result.Ok(100); + + value.Should().Be(100); + errors.Should().BeNull(); + } + + [Fact] + public void Can_deconstruct_generic_Fail_to_errors_with_value() + { + var error = new Error("fail"); + + var (value, errors) = Result.Fail(error); + + value.Should().Be(default); + + errors.Count.Should().Be(1); + errors.FirstOrDefault().Should().Be(error); + } + + [Fact] public void Can_deconstruct_generic_Ok_to_isSuccess_and_isFailed_and_value_with_errors() { diff --git a/src/FluentResults/Results/Result.cs b/src/FluentResults/Results/Result.cs index 0b03a0b..ee4b359 100644 --- a/src/FluentResults/Results/Result.cs +++ b/src/FluentResults/Results/Result.cs @@ -563,6 +563,17 @@ public void Deconstruct(out bool isSuccess, out bool isFailed, out TValue value, errors = IsFailed ? Errors : default; } + /// + /// Deconstruct Result + /// + /// + /// + public void Deconstruct(out TValue value, out List errors) + { + value = IsSuccess ? Value : default; + errors = IsFailed ? Errors : default; + } + private void ThrowIfFailed() { if (IsFailed)