Skip to content

Commit ab7aa6d

Browse files
authored
feature(Result): add mechanism to execute an action based on the state of the previous result
1 parent 4dc1c46 commit ab7aa6d

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

libraries/core/documentation/monads/result.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Type intended to handle both the possible failure and the expected success of a
3636
- [`Ensure<TAuxiliary>(createAuxiliary, predicate, createFailure)`](#ensuretauxiliarycreateauxiliary-predicate-createfailure)
3737
- [`DoOnFailure(execute)`](#doonfailureexecute)
3838
- [`DoOnSuccess(execute)`](#doonsuccessexecute)
39+
- [`Match(doOnFailure, doOnSuccess)`](#matchdoonfailure-doonsuccess)
3940
- [`Map<TSuccessToMap>(successToMap)`](#maptsuccesstomapsuccesstomap)
4041
- [`Map<TSuccessToMap>(createSuccessToMap)`](#maptsuccesstomapcreatesuccesstomap)
4142
- [`Bind<TSuccessToBind>(createResultToBind)`](#bindtsuccesstobindcreateresulttobind)
@@ -429,6 +430,30 @@ Type of expected success.
429430

430431
***[Top](#resulttfailure-tsuccess)***
431432

433+
#### `Match(doOnFailure, doOnSuccess)`
434+
435+
- Signatures:
436+
437+
- ```cs
438+
public Result<TFailure, TSuccess> Match(Action doOnFailure, Action doOnSuccess)
439+
```
440+
441+
- ```cs
442+
public Result<TFailure, TSuccess> Match(Action<TFailure> doOnFailure, Action<TSuccess> doOnSuccess)
443+
```
444+
445+
- Description: Executes an action based on the state of the previous result.
446+
- Parameters:
447+
448+
| Name | Description |
449+
|:--------------|:-----------------------------------------------------------|
450+
| `doOnFailure` | The action to execute if the previous result is failed |
451+
| `doOnSuccess` | The action to execute if the previous result is successful |
452+
453+
- Return: The previous result.
454+
455+
***[Top](#resulttfailure-tsuccess)***
456+
432457
#### `Map<TSuccessToMap>(successToMap)`
433458

434459
- Signature:

libraries/core/source/Monads/Result.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,36 @@ public Result<TFailure, TSuccess> DoOnSuccess(Action<TSuccess> execute)
224224
return this;
225225
}
226226

227+
/// <summary>Executes an actions based on the state of the previous result.</summary>
228+
/// <param name="doOnFailure">The action to execute if the previous result is failed.</param>
229+
/// <param name="doOnSuccess">The action to execute if the previous result is successful.</param>
230+
/// <returns>The previous result.</returns>
231+
public Result<TFailure, TSuccess> Match(Action doOnFailure, Action doOnSuccess)
232+
{
233+
if (IsFailed)
234+
{
235+
doOnFailure();
236+
return this;
237+
}
238+
doOnSuccess();
239+
return this;
240+
}
241+
242+
/// <summary>Executes an action based on the state of the previous result.</summary>
243+
/// <param name="doOnFailure">The action to execute if the previous result is failed.</param>
244+
/// <param name="doOnSuccess">The action to execute if the previous result is successful.</param>
245+
/// <returns>The previous result.</returns>
246+
public Result<TFailure, TSuccess> Match(Action<TFailure> doOnFailure, Action<TSuccess> doOnSuccess)
247+
{
248+
if (IsFailed)
249+
{
250+
doOnFailure(Failure);
251+
return this;
252+
}
253+
doOnSuccess(Success);
254+
return this;
255+
}
256+
227257
/// <summary>Maps the expected success to a value of another type.</summary>
228258
/// <param name="successToMap">An expected success to map.</param>
229259
/// <typeparam name="TSuccessToMap">Type of expected success to map.</typeparam>

libraries/core/tests/unit/Monads/ResultTests.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public sealed class ResultTests
2020

2121
private const string memberDoOnSuccess = nameof(Result<object, object>.DoOnSuccess);
2222

23+
private const string memberMatch = nameof(Result<object, object>.Match);
24+
2325
private const string memberMap = nameof(Result<object, object>.Map);
2426

2527
private const string memberBind = nameof(Result<object, object>.Bind);
@@ -578,6 +580,70 @@ public void DoOnSuccess_SuccessfulResultPlusExecuteWithSuccess_SuccessfulResult(
578580

579581
#endregion
580582

583+
#region Match
584+
585+
#region Overload
586+
587+
[Fact]
588+
[Trait(@base, memberMatch)]
589+
public void Match_FailedResultPlusDoOnFailurePlusDoOnSuccess_FailedResult()
590+
{
591+
bool status = false;
592+
Action doOnFailure = () => status = true;
593+
Action doOnSuccess = () => status = false;
594+
Result<string, Constellation> actual = ResultMother.Fail()
595+
.Match(doOnFailure, doOnSuccess);
596+
Assert.True(status);
597+
ResultAsserter.CheckIfIsFailed(actual);
598+
}
599+
600+
[Fact]
601+
[Trait(@base, memberMatch)]
602+
public void Match_SuccessfulResultPlusDoOnFailurePlusDoOnSuccess_SuccessfulResult()
603+
{
604+
bool status = false;
605+
Action doOnFailure = () => status = false;
606+
Action doOnSuccess = () => status = true;
607+
Result<string, Constellation> actual = ResultMother.Succeed()
608+
.Match(doOnFailure, doOnSuccess);
609+
Assert.True(status);
610+
ResultAsserter.CheckIfIsSuccessful(actual);
611+
}
612+
613+
#endregion
614+
615+
#region Overload
616+
617+
[Fact]
618+
[Trait(@base, memberMatch)]
619+
public void Match_FailedResultPlusDoOnFailureWithFailurePlusDoOnSuccessWithSuccess_FailedResult()
620+
{
621+
bool status = false;
622+
Action<string> doOnFailure = _ => status = true;
623+
Action<Constellation> doOnSuccess = _ => status = false;
624+
Result<string, Constellation> actual = ResultMother.Fail()
625+
.Match(doOnFailure, doOnSuccess);
626+
Assert.True(status);
627+
ResultAsserter.CheckIfIsFailed(actual);
628+
}
629+
630+
[Fact]
631+
[Trait(@base, memberMatch)]
632+
public void Match_SuccessfulResultPlusDoOnFailureWithFailurePlusDoOnSuccessWithSuccess_SuccessfulResult()
633+
{
634+
bool status = false;
635+
Action<string> doOnFailure = _ => status = false;
636+
Action<Constellation> doOnSuccess = _ => status = true;
637+
Result<string, Constellation> actual = ResultMother.Succeed()
638+
.Match(doOnFailure, doOnSuccess);
639+
Assert.True(status);
640+
ResultAsserter.CheckIfIsSuccessful(actual);
641+
}
642+
643+
#endregion
644+
645+
#endregion
646+
581647
#region Map
582648

583649
#region Overload

0 commit comments

Comments
 (0)