Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
altmann committed Sep 11, 2022
2 parents 1b4e81f + b0fbfe3 commit dfa786e
Show file tree
Hide file tree
Showing 6 changed files with 1,190 additions and 12 deletions.
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ Result.Ok<int>(5).ToResult<float>(v => v);
Result.Fail<int>("Failed").ToResult<float>();

// converting a result to a result from type Result
Result.Ok<int>().ToResult();
Result.Ok<int>().ToResult();
```

### Implicit conversion from T to success result ```Result<T>```
Expand All @@ -337,6 +337,41 @@ string myString = "hello world";
Result<T> result = myString;
```

### Bind the result to another result

Binding is a transformation that returns a `Result` | `Result<T>`.
It only evaluates the transformation if the original result is successful.
The reasons of both `Result` will be merged into a new flattened `Result`.

```csharp
// converting a result to a result which may fail
Result<string> r = Result.Ok(8)
.Bind(v => v == 5 ? "five" : Result.Fail<string>("It is not five"));

// converting a failed result to a result, which can also fail,
// returns a result with the errors of the first result only,
// the transformation is not evaluated because the value of the first result is not available
Result<string> r = Result.Fail<int>("Not available")
.Bind(v => v == 5 ? "five" : Result.Fail<string>("It is not five"));

// converting a result with value to a Result via a transformation which may fail
Result.Ok(5).Bind(x => Result.OkIf(x == 6, "Number is not 6"));

// converting a result without value into a Result
Result.Ok().Bind(() => Result.Ok(5));

// just running an action if the original result is sucessful.
Result r = Result.Ok().Bind(() => Result.Ok());
```

The `Bind` has asynchronous overloads.

```csharp
var result = await Result.Ok(5)
.Bind(int n => Task.FromResult(Result.Ok(n + 1).WithSuccess("Added one")))
.Bind(int n => /* next continuation */);
```

### Set global factories for ISuccess/IError/IExceptionalError

Within the FluentResults library in some scenarios an ISuccess, IError or IExceptionalError object is created. For example if the method ```Result.Fail("My Error")``` is called then internally an IError object is created. If you need to overwrite this behavior and create in this scenario a custom error class then you can set the error factory via the settings. The same extension points are also available for ISuccess and IExceptionalError.
Expand Down
40 changes: 31 additions & 9 deletions src/FluentResults.Test/Playground.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using FluentResults.Extensions;

namespace FluentResults.Test
{
Expand All @@ -21,31 +23,30 @@ public void Simple()
var voidResult = Result.Ok();

voidResult = Result.Ok()
.WithSuccess("This is a success")
.WithSuccess("This is a second success");
.WithSuccess("This is a success")
.WithSuccess("This is a second success");

voidResult = Result.Fail("First error");

voidResult = Result.Fail(new Error("First error"));

voidResult = Result.Fail("First error")
.WithError("second error")
.WithError(new CustomError().CausedBy(new InvalidCastException()));

.WithError("second error")
.WithError(new CustomError().CausedBy(new InvalidCastException()));

var valueResult = Result.Ok<int>(default)
.WithSuccess("first success")
.WithValue(3);
.WithSuccess("first success")
.WithValue(3);

valueResult = Result.Ok(3);

valueResult = Result.Ok<int>(default)
.WithValue(3);
.WithValue(3);

valueResult = Result.Fail<int>("First error");

valueResult = Result.Fail<int>(new Error("first error"))
.WithError("second error");
.WithError("second error");

IEnumerable<Result> results = new List<Result>();
Result mergedResult = results.Merge();
Expand Down Expand Up @@ -89,5 +90,26 @@ public void LogTest()
var result1 = Result.Ok();
result1 = result1.Log();
}

public async Task BindTests()
{
var r = Result.Ok(1);

var r1 = await r.Bind(v => GetVResult())
.Bind(v => GetVResultAsync())
.Bind(v => GetVResult())
.Bind(v => GetVResultAsync())
;

var r2 = await r.Bind(v => GetVResultAsync());
}

private Result GetResult() => Result.Ok();

private Result<int> GetVResult() => Result.Ok(1);

private Task<Result> GetResultAsync() => Task.FromResult(GetResult());

private Task<Result<int>> GetVResultAsync() => Task.FromResult(GetVResult());
}
}
Loading

0 comments on commit dfa786e

Please sign in to comment.