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
82
83
84
//! `Resolve<S>` — typed application resource resolution (A8, ADR-0004).
//!
//! The mechanism Arcature uses instead of a runtime DI container. A type
//! implementing `Resolve<S>` can be constructed from application state `S` —
//! cheaply, at compile time, with no `HashMap<TypeId, Box<dyn Any>>`, no
//! runtime reflection, no service locator (AGENTS.md §17/§19/§20).
//!
//! The `#[service]` proc-macro generates `impl Resolve<S>` for service
//! types, composing from the `Resolve<S>` impls of their field types.
//! Built-in resources (`Db`) have `Resolve<S>` impls provided by Arcature
//! via their `*FromState` traits.
//!
//! `Resolve<S>` is the construction trait; [`Inject<T>`](super::service::Inject)
//! is the Axum extractor that calls `T::resolve(state)` on the request path.
//!
//! # Lifetime model
//!
//! - **Application resource** (startup): lives in application state `S`.
//! - **Service** (request): cheap composition from `S` via `Resolve<S>`.
//! - **Request value** (current request): derived from request parts.
//!
//! Services are NOT singletons. A `#[service]` is constructed per request
//! from `Arc`/`Clone`-backed application resources. This is cheap because
//! the underlying handles (`Db`, `Cache`, …) are `Clone` and backed by
//! `Arc` pools.
/// How to construct a value of type `Self` from application state `S`.
///
/// Implementations are generated by `#[service]` for service types and
/// provided by Arcature for built-in resources. The trait is the typed
/// replacement for a runtime DI container (ADR-0004): no `TypeId`, no
/// `Any`, no runtime lookup.
///
/// # Example
///
/// ```ignore
/// // Arcature provides this for Db (behind `dx` + `db`):
/// impl<S> Resolve<S> for Db
/// where Db: DbFromState<S>, S: Send + Sync
/// {
/// fn resolve(state: &S) -> Self { Db::db_from_state(state) }
/// }
///
/// // #[service] generates this for LinkService:
/// impl<S> Resolve<S> for LinkService
/// where Db: Resolve<S>, Cache: Resolve<S>, S: Send + Sync
/// {
/// fn resolve(state: &S) -> Self {
/// LinkService {
/// db: Db::resolve(state),
/// cache: Cache::resolve(state),
/// }
/// }
/// }
/// ```
// Built-in resource impls: Arcature provides `Resolve<S>` for the
// subsystem handles it owns the `*FromState` trait for. Each is gated
// behind the feature that enables that subsystem.
//
// For resources without a provided `Resolve<S>` impl (e.g. a user-defined
// Stripe client), the application writes a one-line impl:
//
// impl Resolve<AppState> for StripeClient {
// fn resolve(state: &AppState) -> Self { state.stripe.clone() }
// }
/// `Resolve<S>` for `Db` — delegates to the existing `DbFromState<S>`
/// trait from A7. Behind `dx` + `db` (DbFromState requires Db).