# Effect-rs
**A high-performance, strictly-typed, functional effect system for Rust.**
> ⚠️ **Note**: This project is currently in active development / alpha stage.
`Effect-rs` brings the power of functional effect systems (inspired by ZIO, Cats Effect) to the Rust ecosystem. It provides a robust framework for building asynchronous, concurrent, and resilient applications with ease.
## Key Features
- **Effect<R, E, A>**: The core generic type representing a lazy computation that requires an environment `R`, may fail with `E`, or succeed with `A`.
- **Structured Concurrency**: Lightweight fibers with automatic cancellation propagation and resource safety.
- **Dependency Injection**: Type-safe environment management built directly into the `Effect` type.
- **Software Transactional Memory (STM)**: Composable, atomic transactions for managing shared state without deadlocks.
- **Streams**: Purely functional, pull-based streams for processing data pipelines efficiently.
- **Resilience**: Built-in `Schedule` and `Retry` policies to handle failures gracefully.
- **Testkit**: Deterministic `TestRuntime` and `TestClock` for reliable, time-dependent testing.
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
effect-rs = "0.1.0"
tokio = { version = "1", features = ["full"] }
```
## Quick Start
### Basic Effect
```rust
use effect_rs::{Effect, Runtime};
fn main() {
let program = Effect::succeed("Hello, World!")
.map(|msg| println!("{}", msg));
Runtime::new().block_on(program, ());
}
```
### Dependency Injection
```rust
use effect_rs::{Effect, Runtime, EnvRef};
use std::sync::Arc;
struct Config {
app_name: String,
}
fn print_config() -> Effect<Arc<Config>, (), ()> {
Effect::access_async(|env: EnvRef<Arc<Config>>, _| async move {
println!("Running app: {}", env.value.app_name);
})
}
fn main() {
let config = Arc::new(Config { app_name: "MyEffectApp".into() });
let rt = Runtime::new();
rt.block_on(print_config(), config);
}
```
### Concurrency & Fibers
```rust
use effect_rs::{Effect, Runtime};
use std::time::Duration;
fn main() {
let rt = Runtime::new();
let program = Effect::succeed(1)
.delay(Duration::from_millis(100))
.fork() // Run in a separate fiber
.flat_map(|fiber| {
println!("Fiber started!");
fiber.join() // Wait for result
})
.map(|res| println!("Result: {}", res));
rt.block_on(program, ());
}
```
## Philosophy
`Effect-rs` aims to bridge the gap between Rust's zero-cost abstractions and the expressive power of functional programming. By treating side effects as values, we gain:
- **Referential Transparency**: Easier reasoning and refactoring.
- ** composability**: Build complex logic from simple, reusable blocks.
- **Type Safety**: Errors and dependencies are explicit in the type signature.
## Running Examples
The project includes several examples demonstrating key features. You can run them using the provided `Makefile`:
- **Transactional Bank (STM)**: `make run-bank`
- **Stream Pipeline**: `make run-stream`
- **HTTP Service Mock**: `make run-http`
### Running Benchmarks
Performance benchmarks are available for core components:
- **Run All**: `make bench`
- **Fiber Operations**: `make bench-fiber`
- **Runtime Overhead**: `make bench-runtime`
- **STM Transactions**: `make bench-stm`
- **Stream Processing**: `make bench-stream`
Or using Cargo directly:
```bash
cargo run --example transactional_bank
```
## License
This project is licensed under the MIT License.