arcature 2026.2.1

Arcature application framework: a high-level Application facade over the certified Arcature subsystems, with the low-level Axum/Tower escape hatch preserved.
Documentation
//! `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),
///         }
///     }
/// }
/// ```
pub trait Resolve<S>: Send + Sync + 'static {
    /// Construct `Self` from application state `S`.
    fn resolve(state: &S) -> Self;
}

// 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).
#[cfg(all(feature = "dx", feature = "db"))]
impl<S> Resolve<S> for crate::db::Db
where
    crate::db::Db: crate::dx::db_from_state::DbFromState<S>,
    S: Send + Sync,
{
    fn resolve(state: &S) -> Self {
        use crate::dx::db_from_state::DbFromState;
        crate::db::Db::db_from_state(state)
    }
}