rainier_support/lib.rs
1//! # rainier-support
2//!
3//! The primitives every other Rainier crate shares, and nothing else. It sits
4//! at the bottom of the dependency graph and depends on no other Rainier crate,
5//! which is what lets the components above it stay independent of each other.
6//!
7//! - [`Error`] / [`Result`] — one error type, carrying the status and the
8//! structured details the HTTP layer needs to render any failure.
9//! - [`Extensions`] — the type-keyed bag behind request attributes and
10//! container bindings.
11//! - [`str`](mod@str) — the inflection vocabulary resource routing and the code
12//! generators are written against.
13//! - [`Setting`] / [`setting_enum!`] — a closed set of config values, so a
14//! driver name is an enum rather than a string nobody validates.
15//! - [`BoxFuture`] — the boxed future the framework's `dyn`-safe async traits
16//! return.
17
18#![deny(missing_docs)]
19#![deny(rustdoc::broken_intra_doc_links)]
20
21pub mod build_info;
22pub mod error;
23pub mod extensions;
24pub mod setting;
25pub mod str;
26
27pub use build_info::BuildInfo;
28pub use error::{Context, Error, ErrorKind, Result};
29pub use extensions::Extensions;
30pub use setting::Setting;
31
32/// What [`setting_enum!`] expands to. Not a stable API.
33///
34/// Re-exporting `serde` here is what lets a crate declare a setting without
35/// naming serde in its own manifest — the macro reaches it through `$crate`.
36#[doc(hidden)]
37pub mod __private {
38 pub use serde;
39}
40
41use std::future::Future;
42use std::pin::Pin;
43
44/// A heap-allocated, `Send` future — the return type of every `dyn`-safe async
45/// method in the framework.
46///
47/// Rust's `async fn` in traits produces an unnameable opaque type, which cannot
48/// be put behind `dyn`. Every Rainier contract that needs to be a trait object
49/// (middleware, queue drivers, mail transports, auth guards) therefore returns
50/// this instead. Where a contract does *not* need to be a trait object it uses
51/// plain `async fn` and stays allocation-free.
52pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
53
54/// A `'static` [`BoxFuture`], for futures that outlive the call that made them
55/// (a spawned job, a queued listener).
56pub type BoxedFuture<T> = BoxFuture<'static, T>;
57
58/// A boxed future that is **not** `Send`, and so cannot cross threads.
59///
60/// Used for the few contracts that wrap something inherently thread-bound —
61/// notably the escape hatch onto Rainier ORM's own `Executor` API, whose futures
62/// hold `sea_query` statements (and therefore `Rc`) across their awaits. Code
63/// on the request path should never need this; a handler's future must be
64/// `Send` for the server to spawn it.
65pub type LocalBoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
66
67/// Box a future into a [`BoxFuture`]. Sugar for `Box::pin`, named so call
68/// sites read as intent rather than allocation.
69pub fn boxed<'a, F>(future: F) -> BoxFuture<'a, F::Output>
70where
71 F: Future + Send + 'a,
72{
73 Box::pin(future)
74}
75
76/// The framework's prelude: what nearly every module wants in scope.
77pub mod prelude {
78 pub use crate::error::{Context as _, Error, ErrorKind, Result};
79 pub use crate::extensions::Extensions;
80 pub use crate::setting::Setting as _;
81 pub use crate::{boxed, BoxFuture, BoxedFuture, LocalBoxFuture};
82}