arcature 2026.2.0

Arcature application framework: a high-level Application facade over the certified Arcature subsystems, with the low-level Axum/Tower escape hatch preserved.
Documentation
//! The curated Arcature prelude.
//!
//! `use arcature::prelude::*;` brings the normal-user surface into scope: the
//! [`Application`] engine, the low-level [`App`] kernel, the [`Routes`]
//! router alias, routing functions, common extractors and response helpers,
//! the engine [`Result`], and (when the `serde` feature is on) Serde's
//! `Serialize`/`Deserialize`.
//!
//! The prelude is deliberately *curated*, not a glob of every dependency (engine
//! spec §19): it avoids name collisions and wildcard re-exports of entire
//! upstream crates. The full surface of each subsystem lives under its facade
//! module (e.g. `arcature::inertia`, `arcature::db`) — reach for those when you
//! need a type not in the prelude.
//!
//! # Selected capability types
//!
//! When a subsystem feature is enabled, the prelude re-exports its primary
//! entry-point type so normal application code rarely needs a qualified path:
//!
//! | Feature    | Prelude export |
//! |------------|----------------|
//! | `inertia`  | `Inertia` |
//! | `db`       | `Db` |
//! | `auth`     | (use `arcature::auth` directly — sessions/CSRF/OAuth are context-dependent) |
//! | `cache`    | `Cache` |
//! | `storage`  | `Storage` |
//! | `mail`     | `Mailer` |
//! | `jobs`     | `Jobs` |
//! | `pages`    | `Pages` |
//! | `observe`  | `RequestId` |
//! | `api`      | `Problem` |
//!
//! Enabling a feature *compiles* these APIs through the facade; it does not
//! connect to a runtime service (engine spec §14).

// Framework-owned types (always available — no feature gate).
pub use crate::app::App;
pub use crate::application::Application;
pub use crate::application::Result;
pub use crate::proxy::ProxyAction;
pub use crate::proxy::ProxyRequest;
pub use crate::routing::Routes;

// Routing constructors (the certified Axum functions, re-exported so normal
// code never names `axum::` directly).
pub use crate::routing::{any, delete, from_fn, get, head, options, patch, post, put};

// Common HTTP extractors. `State` and `Path` live in `axum-core` and are
// always available. `Json`/`Query`/`Form` require axum's `json`/`query`/`form`
// features, which are activated by the `api` feature (arcature-api enables
// them); they are re-exported only when `api` is on so the minimal kernel
// stays minimal (engine spec §55).
pub use crate::axum::extract::{Path, State};

// Body-decoding extractors — available when the `api` feature activates
// axum's `json`/`query`/`form` features via arcature-api.
//
// `Json` is re-exported from axum here ONLY when the A4 `dx::Json` is not
// available (i.e. when `dx` + `serde` are both on, the higher-level
// `dx::Json` takes precedence and is re-exported below instead). This
// avoids a name collision when both `api` and `dx`+`serde` are enabled.
#[cfg(all(feature = "api", not(all(feature = "dx", feature = "serde"))))]
pub use crate::axum::extract::{Form, Json, Query};
#[cfg(all(feature = "api", all(feature = "dx", feature = "serde")))]
pub use crate::axum::extract::{Form, Query};

// Common response helpers.
pub use crate::axum::http::{HeaderMap, StatusCode, Uri};
pub use crate::axum::response::{IntoResponse, Redirect, Response};

// A4: high-level response types. `Empty` is always available when `dx` is on.
// `Json` and `Page` require `serde` (for serialization), so they are gated.
//
// When `dx`+`serde` and `api` are both on, `dx::Json` takes precedence over
// the raw `axum::Json` extractor — the axum re-export is suppressed above in
// that configuration so there is no name collision in the prelude.
#[cfg(feature = "dx")]
pub use crate::dx::Empty;
#[cfg(all(feature = "dx", feature = "serde"))]
pub use crate::dx::Json;
#[cfg(all(feature = "dx", feature = "serde"))]
pub use crate::dx::Page;
#[cfg(all(feature = "dx", feature = "serde"))]
pub use crate::dx::page;

// A5: the validated request extractor. `Validated<T>` combines JSON body
// extraction + deserialization + validation into one Axum `FromRequest`.
// Behind `dx` + `api` (needs `validator::Validate` and the `arcature-api`
// Problem infrastructure for 422 error responses).
#[cfg(all(feature = "dx", feature = "api"))]
pub use crate::dx::Validated;

// A6: page and resource DX macros.
//
// `#[page("name")]` (attribute) and `#[resource]` (attribute) are proc-macro
// attributes re-exported at the crate root and brought into scope here. They
// generate `impl ClientData`, `Serialize` derive, and (for `#[page]`) a
// `PageContract` const.
//
// `page!(...)` constructs a `Page<T>` with a compile-time `ClientData`
// assertion. Rust does not allow a function-like macro and an attribute
// macro to share the same name in one module, so the function-like proc
// macro is named `page_macro` at the crate root. Applications import it with
// a local rename: `use arcature::page_macro as page;` — or call it as
// `arcature::page_macro!(...)`.
#[cfg(all(feature = "dx", feature = "inertia"))]
pub use crate::page;
#[cfg(all(feature = "dx", feature = "inertia"))]
pub use crate::page_macro;
#[cfg(all(feature = "dx", feature = "inertia"))]
pub use crate::resource;

// A7: route model binding. `RouteModel` is the trait a type implements to
// be loadable from the database by a route parameter. `Bound<T>` is the
// Axum extractor that loads the model and returns 404 on miss. Behind
// `dx` + `db` (+ `api` for Bound, which produces Problem responses).
#[cfg(all(feature = "dx", feature = "db", feature = "api"))]
pub use crate::Bound;
#[cfg(all(feature = "dx", feature = "db"))]
pub use crate::RouteModel;
#[cfg(all(feature = "dx", feature = "db"))]
pub use crate::route_model;

// A8: typed services/providers (ADR-0004). `#[service]` generates `impl
// Resolve<S>` + `impl Service` + `impl DxComponent`; `#[provider]` generates
// `impl DxComponent` (the developer writes `impl Provider` by hand). `Inject<T>`
// is the Axum extractor that constructs any `T: Resolve<S>` from state. `Resolve`
// is the typed resolution trait — no runtime container (no TypeId/Any).
// `Service` and `Provider` are marker traits for `arc check` graph validation.
// Behind `dx` (services/providers are pure composition, not tied to a subsystem).
#[cfg(feature = "dx")]
pub use crate::provider;
#[cfg(feature = "dx")]
pub use crate::service;
#[cfg(feature = "dx")]
pub use crate::{Inject, Provider, Resolve, Service};

// A9: auth/policies/session/flash (ADR-0004). Behind `dx` + `auth`.
// `#[policy]` generates `impl DxComponent` only (the developer writes
// `impl Policy<M>` by hand — the authorization logic is business
// behavior). `Auth<User>`, `OptionalAuth<User>`, `AuthManager<User>`,
// `Session`, and `Flash` are genuine Axum `FromRequestParts` extractors.
// `AuthUser` and `UserLoader` are the application identity contracts.
#[cfg(all(feature = "dx", feature = "auth"))]
pub use crate::policy;
#[cfg(all(feature = "dx", feature = "auth"))]
pub use crate::{
    Auth, AuthError, AuthManager, AuthUser, AuthzError, Current, Flash, FlashError, FlashLevel,
    FlashMessage, LoginBuilder, OptionalAuth, OptionalCurrent, Policy, Session, SessionError,
    UserLoader,
};

// A10: the middleware attribute macro and the global error-mapping function.
// `#[middleware]` validates a function signature and passes it through
// unchanged so it remains a genuine Axum `from_fn` middleware. `ErrorMapFn`
// is installed via `Application::error_mapping(...)`. Behind `dx`.
#[cfg(feature = "dx")]
pub use crate::ErrorMapFn;
#[cfg(feature = "dx")]
pub use crate::middleware;

// A11: typed events and the event dispatcher. `#[derive(Event)]` marks a
// struct as a typed event. `#[listener(Event)]` annotates a listener
// function. `Dispatcher` is the in-process event dispatcher. Behind `dx` +
// `serde` (events are type-erased via `serde_json::Value`).
#[cfg(all(feature = "dx", feature = "serde"))]
pub use crate::Event;
#[cfg(all(feature = "dx", feature = "serde"))]
pub use crate::{DispatchError, Dispatcher, ListenerBinding, listener};

// A12: the jobs/scheduler/commands DX layer. `#[derive(Job)]` declares a
// struct as a typed job. `#[job_handler]` annotates a job handler function.
// `#[command("name")]` annotates an application command function. `Scheduler`
// is the managed recurring-job enqueuer. `CommandRegistry` is the type-erased
// command dispatcher for `arc run`. The binding types (`JobBinding`,
// `CommandBinding`, `ScheduleBinding`, `ScheduleCadence`) support `arc
// check` / `arc modules` / `arc schedule` inspection. Behind `dx` + `jobs`
// (and `serde` for `Job` — the derive macro and the trait share the name
// `Job` in different namespaces, like `serde::Serialize`).
#[cfg(all(feature = "dx", feature = "jobs", feature = "serde"))]
pub use crate::Job;
#[cfg(all(feature = "dx", feature = "jobs"))]
pub use crate::{
    Command, CommandBinding, CommandError, CommandRegistry, JobBinding, ScheduleBinding,
    ScheduleCadence, Scheduler, SchedulerError, command, job_handler,
};

// Serde surface (opt-in via the `serde` feature, or transitively via
// `inertia`/`api`). Lets a normal app derive `Serialize`/`Deserialize` for
// props/models without a direct `serde` dependency (engine spec §44).
#[cfg(feature = "serde")]
pub use serde::{Deserialize, Serialize};

// A5: the validator trait. `Validate` is re-exported so `#[request]`
// structs' `impl Validate` is accessible through the prelude, and so
// handlers can bound on `T: Validate` if needed. Behind `validation`
// (enabled by `api`).
#[cfg(feature = "validation")]
pub use validator::Validate;

// Selected capability entry points — one primary type per enabled subsystem.
// The full surface of each lives under its facade module (`crate::<subsystem>`).
#[cfg(feature = "api")]
pub use crate::api::Problem;
#[cfg(feature = "cache")]
pub use crate::cache::Cache;
#[cfg(feature = "db")]
pub use crate::db::Db;
#[cfg(feature = "inertia")]
pub use crate::inertia::Inertia;
#[cfg(feature = "jobs")]
pub use crate::jobs::Jobs;
#[cfg(feature = "mail")]
pub use crate::mail::Mailer;
#[cfg(feature = "observe")]
pub use crate::observe::RequestId;
#[cfg(feature = "pages")]
pub use crate::pages::Pages;
#[cfg(feature = "storage")]
pub use crate::storage::Storage;