1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! Effect trait definition - the core abstraction for zero-cost effects.
//!
//! This module defines the `Effect` trait, which represents a computation that:
//! - Produces a value of type `Output` on success
//! - May fail with an error of type `Error`
//! - Depends on an environment of type `Env`
//!
//! # Design Philosophy
//!
//! This trait follows the same pattern as `Future` and `Iterator`:
//! - Combinators return concrete types (zero-cost abstractions)
//! - Use `.boxed()` when you need type erasure
//!
//! # Environment Cloning
//!
//! The `Env` type requires `Clone` to enable boxing. When an effect is boxed,
//! the environment must be cloned into the boxed future to achieve `'static`
//! lifetime. This is typically cheap when environments contain `Arc`-wrapped
//! resources:
//!
//! ```rust,ignore
//! #[derive(Clone)]
//! struct AppEnv {
//! db: Arc<DatabasePool>,
//! config: Arc<Config>,
//! http: Arc<HttpClient>,
//! }
//! ```
use Future;
/// The core Effect trait - represents a computation that may perform effects.
///
/// This trait is the foundation of Stillwater's zero-cost effect system.
/// Unlike the boxed `Effect` struct, implementing types can be zero-sized
/// when possible, and combinators return concrete types rather than boxed
/// trait objects.
///
/// # Type Parameters
///
/// * `Output` - The success type produced by this effect (must be `Send`)
/// * `Error` - The error type that may be produced (must be `Send`)
/// * `Env` - The environment type required to run this effect (must be `Clone + Send + Sync`)
///
/// # Example
///
/// ```rust,ignore
/// use stillwater::effect::prelude::*;
///
/// fn fetch_user(id: i32) -> impl Effect<Output = User, Error = DbError, Env = AppEnv> {
/// asks(|env: &AppEnv| env.db.clone())
/// .and_then(move |db| from_async(move |_| db.fetch_user(id)))
/// }
/// ```