Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
amantinband committed Mar 26, 2024
1 parent 514d5a1 commit d0f0ebd
Showing 1 changed file with 64 additions and 22 deletions.
86 changes: 64 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@
- [`Then`](#then)
- [`Then`](#then-1)
- [`ThenAsync`](#thenasync)
- [Mixing `Then` and `ThenAsync`](#mixing-then-and-thenasync)
- [`ThenDo` and `ThenDoAsync`](#thendo-and-thendoasync)
- [Mixing `Then`, `ThenDo`, `ThenAsync`, `ThenDoAsync`](#mixing-then-thendo-thenasync-thendoasync)
- [`FailIf`](#failif)
- [`Else`](#else)
- [`Else`](#else-1)
- [`ElseAsync`](#elseasync)
- [Mixing Features (`Then`, `Else`, `Switch`, `Match`)](#mixing-features-then-else-switch-match)
- [Mixing Features (`Then`, `FailIf`, `Else`, `Switch`, `Match`)](#mixing-features-then-failif-else-switch-match)
- [Error Types](#error-types)
- [Built in error types](#built-in-error-types)
- [Custom error types](#custom-error-types)
Expand Down Expand Up @@ -133,9 +135,9 @@ Divide(4, 2)
```cs
ErrorOr<string> foo = await "2".ToErrorOr()
.Then(int.Parse) // 2
.When(val => val > 2, Error.Validation(description: $"{val} is too big") // 2
.ThenAsync(Task.Delay) // Sleep for 2 milliseconds
.Then(val => Console.WriteLine($"Finished waiting {val} milliseconds.")) // Finished waiting 2 milliseconds.
.FailIf(val => val > 2, Error.Validation(description: $"{val} is too big") // 2
.ThenDoAsync(Task.Delay) // Sleep for 2 milliseconds
.ThenDo(val => Console.WriteLine($"Finished waiting {val} milliseconds.")) // Finished waiting 2 milliseconds.
.ThenAsync(val => Task.FromResult(val * 2)) // 4
.Then(val => $"The result is {val}") // "The result is 4"
.Else(errors => Error.Unexpected(description: "Yikes")) // "The result is 4"
Expand All @@ -147,9 +149,9 @@ ErrorOr<string> foo = await "2".ToErrorOr()
```cs
ErrorOr<string> foo = await "5".ToErrorOr()
.Then(int.Parse) // 5
.When(val => val > 2, Error.Validation(description: $"{val} is too big") // 2
.ThenAsync(Task.Delay) // Error.Validation()
.Then(val => Console.WriteLine($"Finished waiting {val} milliseconds.")) // Error.Validation()
.FailIf(val => val > 2, Error.Validation(description: $"{val} is too big") // 2
.ThenDoAsync(Task.Delay) // Error.Validation()
.ThenDo(val => Console.WriteLine($"Finished waiting {val} milliseconds.")) // Error.Validation()
.ThenAsync(val => Task.FromResult(val * 2)) // Error.Validation()
.Then(val => $"The result is {val}") // Error.Validation()
.Else(errors => Error.Unexpected(description: "Yikes")) // Error.Unexpected()
Expand Down Expand Up @@ -225,7 +227,7 @@ return await _userRepository.GetByIdAsync(id)
.Then(user => user.IncrementAge()
.Then(success => user)
.Else(errors => Error.Unexpected("Not expected to fail")))
.When(user => !user.IsOverAge(18), UserErrors.UnderAge)
.FailIf(user => !user.IsOverAge(18), UserErrors.UnderAge)
.ThenDo(user => _logger.LogInformation($"User {user.Id} incremented age to {user.Age}"))
.ThenAsync(user => _userRepository.UpdateAsync(user))
.Finally(
Expand All @@ -236,7 +238,7 @@ return await _userRepository.GetByIdAsync(id)
```cs
return await _userRepository.GetByIdAsync(id)
.Then(user => user.IncrementAge().Then(success => user))
.When(user => !user.IsOverAge(18), UserErrors.UnderAge)
.FailIf(user => !user.IsOverAge(18), UserErrors.UnderAge)
.ThenDo(user => _logger.LogInformation($"User {user.Id} incremented age to {user.Age}"))
.ThenAsync(user => _userRepository.UpdateAsync(user))
.Match(
Expand Down Expand Up @@ -523,7 +525,7 @@ await result.SwitchFirstAsync(

### `Then`

`Then` receives an action or a function, and invokes it only if the result is not an error.
`Then` receives a function, and invokes it only if the result is not an error.

```cs
ErrorOr<int> foo = result
Expand Down Expand Up @@ -552,26 +554,65 @@ ErrorOr<string> foo = result

### `ThenAsync`

`ThenAsync` receives an asynchronous action or function, and invokes it only if the result is not an error.
`ThenAsync` receives an asynchronous function, and invokes it only if the result is not an error.

```cs
ErrorOr<string> foo = await result
.ThenAsync(val => Task.Delay(val))
.ThenAsync(val => Task.FromResult($"The result is {val}"));
.ThenAsync(val => DoSomethingAsync(val))
.ThenAsync(val => DoSomethingElseAsync($"The result is {val}"));
```

### Mixing `Then` and `ThenAsync`
### `ThenDo` and `ThenDoAsync`

You can mix `Then` and `ThenAsync` methods together.
`ThenDo` and `ThenDoAsync` are similar to `Then` and `ThenAsync`, but instead of invoking a function that returns a value, they invoke an action.

```cs
ErrorOr<string> foo = result
.ThenDo(val => Console.WriteLine(val))
.ThenDo(val => Console.WriteLine($"The result is {val}"));
```

```cs
ErrorOr<string> foo = await result
.ThenAsync(val => Task.Delay(val))
.Then(val => Console.WriteLine($"Finsihed waiting {val} seconds."))
.ThenDoAsync(val => Task.Delay(val))
.ThenDo(val => Console.WriteLine($"Finsihed waiting {val} seconds."))
.ThenDoAsync(val => Task.FromResult(val * 2))
.ThenDo(val => $"The result is {val}");
```

### Mixing `Then`, `ThenDo`, `ThenAsync`, `ThenDoAsync`

You can mix and match `Then`, `ThenDo`, `ThenAsync`, `ThenDoAsync` methods.

```cs
ErrorOr<string> foo = await result
.ThenDoAsync(val => Task.Delay(val))
.Then(val => val * 2)
.ThenAsync(val => DoSomethingAsync(val))
.ThenDo(val => Console.WriteLine($"Finsihed waiting {val} seconds."))
.ThenAsync(val => Task.FromResult(val * 2))
.Then(val => $"The result is {val}");
```

## `FailIf`

`FailIf` receives a predicate and an error. If the predicate is true, `FailIf` will return the error. Otherwise, it will return the value of the result.

```cs
ErrorOr<int> foo = result
.FailIf(val => val > 2, Error.Validation(description: $"{val} is too big"));
```

Once an error is returned, the chain will break and the error will be returned.

```cs
var result = "2".ToErrorOr()
.Then(int.Parse) // 2
.FailIf(val => val > 1, Error.Validation(description: $"{val} is too big") // validation error
.Then(num => num * 2) // this function will not be invoked
.Then(num => num * 2) // this function will not be invoked
```

## `Else`

`Else` receives a value or a function. If the result is an error, `Else` will return the value or invoke the function. Otherwise, it will return the value of the result.
Expand Down Expand Up @@ -600,14 +641,15 @@ ErrorOr<string> foo = await result
.ElseAsync(errors => Task.FromResult($"{errors.Count} errors occurred."));
```

# Mixing Features (`Then`, `Else`, `Switch`, `Match`)
# Mixing Features (`Then`, `FailIf`, `Else`, `Switch`, `Match`)

You can mix `Then`, `Else`, `Switch` and `Match` methods together.
You can mix `Then`, `FailIf`, `Else`, `Switch` and `Match` methods together.

```cs
ErrorOr<string> foo = await result
.ThenAsync(val => Task.Delay(val))
.Then(val => Console.WriteLine($"Finsihed waiting {val} seconds."))
.ThenDoAsync(val => Task.Delay(val))
.FailIf(val => val > 2, Error.Validation(description: $"{val} is too big"))
.ThenDo(val => Console.WriteLine($"Finished waiting {val} seconds."))
.ThenAsync(val => Task.FromResult(val * 2))
.Then(val => $"The result is {val}")
.Else(errors => Error.Unexpected())
Expand Down

0 comments on commit d0f0ebd

Please sign in to comment.