diff --git a/CSharpFunctionalExtensions.Tests/ResultTests/CombineMethodTests.cs b/CSharpFunctionalExtensions.Tests/ResultTests/CombineMethodTests.cs index d10c1d95..58032bb9 100644 --- a/CSharpFunctionalExtensions.Tests/ResultTests/CombineMethodTests.cs +++ b/CSharpFunctionalExtensions.Tests/ResultTests/CombineMethodTests.cs @@ -13,7 +13,7 @@ public class CombineMethodTests [Fact] public void Combine_combines_all_errors_together() { - Result result1 = Result.Success(); + Result result1 = Result.Success(1); Result result2 = Result.Failure("Failure 1"); Result result3 = Result.Failure("Failure 2"); diff --git a/CSharpFunctionalExtensions.Tests/ResultTests/CombineSequentialMethodTests.cs b/CSharpFunctionalExtensions.Tests/ResultTests/CombineSequentialMethodTests.cs new file mode 100644 index 00000000..e5cc52cd --- /dev/null +++ b/CSharpFunctionalExtensions.Tests/ResultTests/CombineSequentialMethodTests.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using FluentAssertions; + +using Xunit; + +using static CSharpFunctionalExtensions.Tests.ResultTests.CombineWithErrorMethodTests; + +namespace CSharpFunctionalExtensions.Tests.ResultTests +{ + public class CombineSequentialMethodTests + { + [Fact] + public async Task CombineSequential_execute_all_functions_when_all_are_success() + { + var firstReturnValue = 12; + var secondReturnValue = "value"; + Task> FirstFunction() => Task.FromResult(Result.Success(firstReturnValue)); + + Task> SecondFunction() => Task.FromResult(Result.Success(secondReturnValue)); + + var result = await Result.CombineSequential(FirstFunction, + SecondFunction, + values => new + { + values.DataA, + values.DataB + }); + + result.IsSuccess.Should().BeTrue(); + result.Value.DataA.Should().Be(firstReturnValue); + result.Value.DataB.Should().Be(secondReturnValue); + } + [Fact] + public async Task CombineSequential_execute_first_functions_when_it_fails() + { + var errorValue = "First function error"; + Task> FirstFunction() => Task.FromResult(Result.Failure(errorValue)); + + Task> SecondFunction() => Task.FromResult(Result.Success("value")); + + var result = await Result.CombineSequential(FirstFunction, + SecondFunction, + values => new + { + values.DataA, + values.DataB + }); + result.IsSuccess.Should().BeFalse(); + result.Error.Should().Be(errorValue); + } + [Fact] + public async Task CombineSequential_execute_all_functions_when_second_fails() + { + var errorValue = "Second function error"; + + Task> FirstFunction() => Task.FromResult(Result.Success("value")); + + + Task> SecondFunction() => Task.FromResult(Result.Failure(errorValue)); + + + var result = await Result.CombineSequential(FirstFunction, + SecondFunction, + values => new + { + values.DataA, + values.DataB + }); + result.IsSuccess.Should().BeFalse(); + result.Error.Should().Be(errorValue); + } + } +} \ No newline at end of file diff --git a/CSharpFunctionalExtensions.Tests/ResultTests/Extensions/CheckIfTests.cs b/CSharpFunctionalExtensions.Tests/ResultTests/Extensions/CheckIfTests.cs index 881907d9..9abac54e 100644 --- a/CSharpFunctionalExtensions.Tests/ResultTests/Extensions/CheckIfTests.cs +++ b/CSharpFunctionalExtensions.Tests/ResultTests/Extensions/CheckIfTests.cs @@ -1,4 +1,5 @@ using FluentAssertions; + using Xunit; namespace CSharpFunctionalExtensions.Tests.ResultTests.Extensions @@ -49,7 +50,7 @@ public void CheckIf_T_executes_func_result_K_E_conditionally_and_returns_self(bo actionExecuted.Should().Be(isSuccess && condition); result.Should().Be(returned); } - + [Theory] [InlineData(true, true)] [InlineData(true, false)] @@ -79,7 +80,7 @@ public void CheckIf_T_executes_func_result_K_E_per_predicate_and_returns_self(bo actionExecuted.Should().Be(isSuccess && condition); result.Should().Be(returned); } - + [Theory] [InlineData(true, true)] [InlineData(true, false)] diff --git a/CSharpFunctionalExtensions/CSharpFunctionalExtensions.csproj b/CSharpFunctionalExtensions/CSharpFunctionalExtensions.csproj index 0693dedc..b01a663a 100644 --- a/CSharpFunctionalExtensions/CSharpFunctionalExtensions.csproj +++ b/CSharpFunctionalExtensions/CSharpFunctionalExtensions.csproj @@ -42,6 +42,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + \ No newline at end of file diff --git a/CSharpFunctionalExtensions/Maybe/MaybeExtensions.cs b/CSharpFunctionalExtensions/Maybe/MaybeExtensions.cs index ce0ab9b1..05ff1f7e 100644 --- a/CSharpFunctionalExtensions/Maybe/MaybeExtensions.cs +++ b/CSharpFunctionalExtensions/Maybe/MaybeExtensions.cs @@ -50,7 +50,16 @@ public static Maybe Where(this Maybe maybe, Func predicate) return Maybe.None; } + public static Result Select(this Result maybe, Func selector) + { + return maybe.Map(selector); + } + [Obsolete("Use Bind instead of this method")] + public static Result Select(this Result maybe, Func> selector) + { + return maybe.Bind(selector); + } public static Maybe Select(this Maybe maybe, Func selector) { return maybe.Map(selector); diff --git a/CSharpFunctionalExtensions/Result/Methods/CombineSequential.cs b/CSharpFunctionalExtensions/Result/Methods/CombineSequential.cs new file mode 100644 index 00000000..595f63c6 --- /dev/null +++ b/CSharpFunctionalExtensions/Result/Methods/CombineSequential.cs @@ -0,0 +1,28 @@ +using System; +using System.Threading.Tasks; + +namespace CSharpFunctionalExtensions +{ + public partial struct Result + { + + /// + /// Combines several results (and any error messages) into a single result. + /// The returned result will be a failure if any of the input are failures. + /// Error message will have the first value of the failure operation + /// + /// Type we will map + /// Type of the function + /// >Type of the function + /// First function that we want to execute + /// Second function that we want to execute + /// Functional to map all the result into + /// + public static async Task> CombineSequential( + Func>> a, + Func>> b, + Func<(TDataA DataA, TDataB DataB), TReturnData> combineFunction) + => await (await a()) + .Bind(async resultA => (await b()).Map(resultB => combineFunction((resultA, resultB)))); + } +} \ No newline at end of file