# About

Flow is a lightweight result type library that enables functional programming patterns in C#. It provides a clean, declarative approach to error handling and optional value management through two core monadic types.

**Flow\<T>** is a simple result type that allows returning either a success or failure value. The library includes extension methods that wrap the core `Map` and `Bind` operations, facilitating the chaining of results for a more declarative, functional approach.

**Potential\<T>** is an Option/Maybe monad that represents values that may or may not exist, providing a type-safe alternative to null checks and nullable types.

### Cross-Boundary Serialization

Flow and all provided failure types are decorated with attributes from both **protobuf-net** and **System.Text.Json**. This enables seamless flow of results across client-server boundaries using either:

* gRPC code-first with protobuf-net serializer
* System.Text.Json serializer

**Note:** The type parameter `T` in `Flow<T>` is not automatically serializable. Developers must ensure the parameter is serializable which may entail adding the appropriate serialization attributes.

### Key Concepts

#### Railway-Oriented Programming

Flow enables railway-oriented programming where operations follow clear success/failure paths. Operations chain together seamlessly, with failures automatically propagating without manual error checking at each step.

#### Short-Circuiting

Flow is short-circuiting: if it's a failure, success functions are not executed; if it's a success, failure functions are not executed. When chaining operations, the same flow passes from start to finish unless changed by a function.

#### The None Type

For operations that don't require a return value, use the `None` type:

```csharp
Flow<None> successFlow = Flow<None>.Success();
// or using implicit operator
Flow<None> successFlow = None.Value;
```

### Failure Types

Flow uses an abstract `Failure` base class with 26+ derived types representing specific failure categories:

* NetworkFailure, DatabaseFailure, FileSystemFailure
* ValidationFailure, SecurityFailure, ConfigurationFailure
* ServiceFailure, CloudStorageFailure, ItemNotFoundFailure
* MessagingFailure, GeneralFailure, ConstraintFailure
* DomainFailure, ApplicationFailure, IOFailure
* HardwareFailure, SystemFailure, ConnectionFailure
* TaskCancellationFailure, InternetConnectionFailure, CacheFailure
* JsonFailure, GrpcFailure, ConversionFailure
* InvalidEntryFailure (with structured validation error support)
* UnknownFailure

#### Special Failure Types

**NoFailure** - Used as a default failure value when Flow is a success.

**InvalidEntryFailure** - Contains a `List<InvalidEntry>` property for reporting multiple validation errors. This type was added for when transforming an invalid `Validated<T>` type from the [`Validated.Core`](https://code-dispenser.gitbook.io/validated-docs) NuGet library. You can do this with your own code/extensions or use the `ToFlow<T>` extension contained within the NuGet library [`Flow.Validated`](https://github.com/code-dispenser/Flow-Validated)

**UnknownFailure** - Has type discriminator 199, allowing additional types to be added. Custom failures need discriminator values greater than 199.

### Philosophy

Flow embraces "errors as data" rather than exceptional circumstances. By making success and failure explicit in the type system, code becomes more predictable, testable, and maintainable. This approach encourages thinking about failure scenarios upfront rather than relying on try-catch blocks for control flow.

### Source Code & Demo

The repository includes a complete demo showing:

* Client-server communication via gRPC code-first
* Custom type serialization (protobuf-net and JSON)
* Database query handling with Flow
* Real-world error handling patterns

View the source code at [github.com/code-dispenser/Flow](https://github.com/code-dispenser/Flow)

#### GitHub Repository:

<https://github.com/code-dispenser/Flow>
