Skip to content

Commit efeeb88

Browse files
authored
Merge pull request #332 from lqkahler/bind-result-unitresult
Bind between Result<T, E> and UnitResult<E>
2 parents 4ac5e52 + 4148db4 commit efeeb88

9 files changed

Lines changed: 277 additions & 1 deletion

File tree

CSharpFunctionalExtensions.Tests/ResultTests/Extensions/BindAsyncBothTests.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,46 @@ public void Bind_T_K_E_AsyncBoth_selects_new_result()
107107
funcParam.Should().Be(T.Value);
108108
AssertSuccess(output);
109109
}
110+
111+
[Fact]
112+
public void Bind_T_E_selects_new_unit_result()
113+
{
114+
Result<T, E> input = Result.Success<T, E>(T.Value);
115+
116+
UnitResult<E> output = input.AsTask().Bind(GetUnitResult_E_WithParam_Task).Result;
117+
118+
funcParam.Should().Be(T.Value);
119+
AssertSuccess(output);
120+
}
121+
122+
[Fact]
123+
public void Bind_T_E_returns_failure_and_does_not_execute_func()
124+
{
125+
Result<T, E> input = Result.Failure<T, E>(E.Value);
126+
127+
UnitResult<E> output = input.AsTask().Bind(GetUnitResult_E_WithParam_Task).Result;
128+
129+
AssertFailure(output);
130+
}
131+
132+
[Fact]
133+
public void Bind_E_selects_new_result()
134+
{
135+
UnitResult<E> input = UnitResult.Success<E>();
136+
137+
UnitResult<E> output = input.AsTask().Bind(GetResult_T_E_Task).Result;
138+
139+
AssertSuccess(output);
140+
}
141+
142+
[Fact]
143+
public void Bind_E_returns_failure_and_does_not_execute_func()
144+
{
145+
UnitResult<E> input = UnitResult.Failure<E>(E.Value);
146+
147+
UnitResult<E> output = input.AsTask().Bind(GetResult_T_E).Result;
148+
149+
AssertFailure(output);
150+
}
110151
}
111152
}

CSharpFunctionalExtensions.Tests/ResultTests/Extensions/BindAsyncLeftTests.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,46 @@ public void Bind_T_K_E_AsyncLeft_selects_new_result()
107107
funcParam.Should().Be(T.Value);
108108
AssertSuccess(output);
109109
}
110+
111+
[Fact]
112+
public void Bind_T_E_selects_new_unit_result()
113+
{
114+
Result<T, E> input = Result.Success<T, E>(T.Value);
115+
116+
UnitResult<E> output = input.AsTask().Bind(GetUnitResult_E_WithParam).Result;
117+
118+
funcParam.Should().Be(T.Value);
119+
AssertSuccess(output);
120+
}
121+
122+
[Fact]
123+
public void Bind_T_E_returns_failure_and_does_not_execute_func()
124+
{
125+
Result<T, E> input = Result.Failure<T, E>(E.Value);
126+
127+
UnitResult<E> output = input.AsTask().Bind(GetUnitResult_E_WithParam).Result;
128+
129+
AssertFailure(output);
130+
}
131+
132+
[Fact]
133+
public void Bind_E_selects_new_result()
134+
{
135+
UnitResult<E> input = UnitResult.Success<E>();
136+
137+
UnitResult<E> output = input.AsTask().Bind(GetResult_T_E).Result;
138+
139+
AssertSuccess(output);
140+
}
141+
142+
[Fact]
143+
public void Bind_E_returns_failure_and_does_not_execute_func()
144+
{
145+
UnitResult<E> input = UnitResult.Failure<E>(E.Value);
146+
147+
UnitResult<E> output = input.AsTask().Bind(GetResult_T_E).Result;
148+
149+
AssertFailure(output);
150+
}
110151
}
111152
}

CSharpFunctionalExtensions.Tests/ResultTests/Extensions/BindAsyncRightTests.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,46 @@ public void Bind_T_K_E_AsyncRight_selects_new_result()
107107
funcParam.Should().Be(T.Value);
108108
AssertSuccess(output);
109109
}
110+
111+
[Fact]
112+
public void Bind_T_E_selects_new_unit_result()
113+
{
114+
Result<T, E> input = Result.Success<T, E>(T.Value);
115+
116+
UnitResult<E> output = input.Bind(GetUnitResult_E_WithParam_Task).Result;
117+
118+
funcParam.Should().Be(T.Value);
119+
AssertSuccess(output);
120+
}
121+
122+
[Fact]
123+
public void Bind_T_E_returns_failure_and_does_not_execute_func()
124+
{
125+
Result<T, E> input = Result.Failure<T, E>(E.Value);
126+
127+
UnitResult<E> output = input.Bind(GetUnitResult_E_WithParam_Task).Result;
128+
129+
AssertFailure(output);
130+
}
131+
132+
[Fact]
133+
public void Bind_E_selects_new_result()
134+
{
135+
UnitResult<E> input = UnitResult.Success<E>();
136+
137+
UnitResult<E> output = input.Bind(GetResult_T_E_Task).Result;
138+
139+
AssertSuccess(output);
140+
}
141+
142+
[Fact]
143+
public void Bind_E_returns_failure_and_does_not_execute_func()
144+
{
145+
UnitResult<E> input = UnitResult.Failure<E>(E.Value);
146+
147+
UnitResult<E> output = input.Bind(GetResult_T_E_Task).Result;
148+
149+
AssertFailure(output);
150+
}
110151
}
111152
}

CSharpFunctionalExtensions.Tests/ResultTests/Extensions/BindTests.cs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void Bind_T_K_selects_new_result()
8686
funcParam.Should().Be(T.Value);
8787
AssertSuccess(output);
8888
}
89-
89+
9090
[Fact]
9191
public void Bind_T_K_E_returns_failure_and_does_not_execute_func()
9292
{
@@ -107,5 +107,46 @@ public void Bind_T_K_E_selects_new_result()
107107
funcParam.Should().Be(T.Value);
108108
AssertSuccess(output);
109109
}
110+
111+
[Fact]
112+
public void Bind_T_E_selects_new_unit_result()
113+
{
114+
Result<T, E> input = Result.Success<T, E>(T.Value);
115+
116+
UnitResult<E> output = input.Bind(GetUnitResult_E_WithParam);
117+
118+
funcParam.Should().Be(T.Value);
119+
AssertSuccess(output);
120+
}
121+
122+
[Fact]
123+
public void Bind_T_E_returns_failure_and_does_not_execute_func()
124+
{
125+
Result<T, E> input = Result.Failure<T, E>(E.Value);
126+
127+
UnitResult<E> output = input.Bind(GetUnitResult_E_WithParam);
128+
129+
AssertFailure(output);
130+
}
131+
132+
[Fact]
133+
public void Bind_E_selects_new_result()
134+
{
135+
UnitResult<E> input = UnitResult.Success<E>();
136+
137+
UnitResult<E> output = input.Bind(GetResult_T_E);
138+
139+
AssertSuccess(output);
140+
}
141+
142+
[Fact]
143+
public void Bind_E_returns_failure_and_does_not_execute_func()
144+
{
145+
UnitResult<E> input = UnitResult.Failure<E>(E.Value);
146+
147+
UnitResult<E> output = input.Bind(GetResult_T_E);
148+
149+
AssertFailure(output);
150+
}
110151
}
111152
}

CSharpFunctionalExtensions.Tests/ResultTests/Extensions/BindTestsBase.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,25 @@ protected Result<K, E> GetResult_K_E_WithParam(T value)
6262
protected Task<Result<K, E>> GetResult_K_E_WithParam_Task(T value)
6363
=> GetResult_K_E_WithParam(value).AsTask();
6464

65+
protected Result<T, E> GetResult_T_E()
66+
{
67+
funcExecuted = true;
68+
return Result.Success<T, E>(T.Value);
69+
}
70+
71+
protected Task<Result<T, E>> GetResult_T_E_Task()
72+
=> GetResult_T_E().AsTask();
73+
74+
protected UnitResult<E> GetUnitResult_E_WithParam(T value)
75+
{
76+
funcExecuted = true;
77+
funcParam = value;
78+
return UnitResult.Success<E>();
79+
}
80+
81+
protected Task<UnitResult<E>> GetUnitResult_E_WithParam_Task(T value)
82+
=> GetUnitResult_E_WithParam(value).AsTask();
83+
6584
protected void AssertFailure(Result output)
6685
{
6786
funcExecuted.Should().BeFalse();
@@ -83,6 +102,13 @@ protected void AssertFailure(Result<K, E> output)
83102
output.Error.Should().Be(E.Value);
84103
}
85104

105+
protected void AssertFailure(UnitResult<E> output)
106+
{
107+
funcExecuted.Should().BeFalse();
108+
output.IsFailure.Should().BeTrue();
109+
output.Error.Should().Be(E.Value);
110+
}
111+
86112
protected void AssertSuccess(Result output)
87113
{
88114
funcExecuted.Should().BeTrue();
@@ -102,5 +128,11 @@ protected void AssertSuccess(Result<K, E> output)
102128
output.IsSuccess.Should().BeTrue();
103129
output.Value.Should().Be(K.Value);
104130
}
131+
132+
protected void AssertSuccess(UnitResult<E> output)
133+
{
134+
funcExecuted.Should().BeTrue();
135+
output.IsSuccess.Should().BeTrue();
136+
}
105137
}
106138
}

CSharpFunctionalExtensions/Result/Extensions/Bind.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,27 @@ public static Result Bind(this Result result, Func<Result> func)
5858

5959
return func();
6060
}
61+
62+
/// <summary>
63+
/// Selects result from the return value of a given function. If the calling Result is a failure, a new failure result is returned instead.
64+
/// </summary>
65+
public static Result<T, E> Bind<T, E>(this UnitResult<E> result, Func<Result<T, E>> func)
66+
{
67+
if (result.IsFailure)
68+
return result.Error;
69+
70+
return func();
71+
}
72+
73+
/// <summary>
74+
/// Selects result from the return value of a given function. If the calling Result is a failure, a new failure result is returned instead.
75+
/// </summary>
76+
public static UnitResult<E> Bind<T, E>(this Result<T, E> result, Func<T, UnitResult<E>> func)
77+
{
78+
if (result.IsFailure)
79+
return result.Error;
80+
81+
return func(result.Value);
82+
}
6183
}
6284
}

CSharpFunctionalExtensions/Result/Extensions/BindAsyncBoth.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,23 @@ public static async Task<Result> Bind(this Task<Result> resultTask, Func<Task<Re
4949
Result result = await resultTask.DefaultAwait();
5050
return await result.Bind(func).DefaultAwait();
5151
}
52+
53+
/// <summary>
54+
/// Selects result from the return value of a given function. If the calling Result is a failure, a new failure result is returned instead.
55+
/// </summary>
56+
public static async Task<Result<T, E>> Bind<T, E>(this Task<UnitResult<E>> resultTask, Func<Task<Result<T, E>>> func)
57+
{
58+
UnitResult<E> result = await resultTask.DefaultAwait();
59+
return await result.Bind(func).DefaultAwait();
60+
}
61+
62+
/// <summary>
63+
/// Selects result from the return value of a given function. If the calling Result is a failure, a new failure result is returned instead.
64+
/// </summary>
65+
public static async Task<UnitResult<E>> Bind<T, E>(this Task<Result<T, E>> resultTask, Func<T, Task<UnitResult<E>>> func)
66+
{
67+
Result<T, E> result = await resultTask.DefaultAwait();
68+
return await result.Bind(func).DefaultAwait();
69+
}
5270
}
5371
}

CSharpFunctionalExtensions/Result/Extensions/BindAsyncLeft.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,23 @@ public static async Task<Result> Bind(this Task<Result> resultTask, Func<Result>
4949
Result result = await resultTask.DefaultAwait();
5050
return result.Bind(func);
5151
}
52+
53+
/// <summary>
54+
/// Selects result from the return value of a given function. If the calling Result is a failure, a new failure result is returned instead.
55+
/// </summary>
56+
public static async Task<Result<T, E>> Bind<T, E>(this Task<UnitResult<E>> resultTask, Func<Result<T, E>> func)
57+
{
58+
UnitResult<E> result = await resultTask.DefaultAwait();
59+
return result.Bind(func);
60+
}
61+
62+
/// <summary>
63+
/// Selects result from the return value of a given function. If the calling Result is a failure, a new failure result is returned instead.
64+
/// </summary>
65+
public static async Task<UnitResult<E>> Bind<T, E>(this Task<Result<T, E>> resultTask, Func<T, UnitResult<E>> func)
66+
{
67+
Result<T, E> result = await resultTask.DefaultAwait();
68+
return result.Bind(func);
69+
}
5270
}
5371
}

CSharpFunctionalExtensions/Result/Extensions/BindAsyncRight.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,27 @@ public static Task<Result> Bind(this Result result, Func<Task<Result>> func)
5959

6060
return func();
6161
}
62+
63+
/// <summary>
64+
/// Selects result from the return value of a given function. If the calling Result is a failure, a new failure result is returned instead.
65+
/// </summary>
66+
public static Task<Result<T, E>> Bind<T, E>(this UnitResult<E> result, Func<Task<Result<T, E>>> func)
67+
{
68+
if (result.IsFailure)
69+
return Result.Failure<T, E>(result.Error).AsCompletedTask();
70+
71+
return func();
72+
}
73+
74+
/// <summary>
75+
/// Selects result from the return value of a given function. If the calling Result is a failure, a new failure result is returned instead.
76+
/// </summary>
77+
public static Task<UnitResult<E>> Bind<T, E>(this Result<T, E> result, Func<T, Task<UnitResult<E>>> func)
78+
{
79+
if (result.IsFailure)
80+
return UnitResult.Failure(result.Error).AsCompletedTask();
81+
82+
return func(result.Value);
83+
}
6284
}
6385
}

0 commit comments

Comments
 (0)