nest_rs_http/boot_check.rs
1//! Boot-time fail-secure checks the HTTP transport runs before mounting
2//! anything.
3//!
4//! The global layer pools are declared as *specs* (`use_guards_global` and
5//! friends) and resolved against the live container at configure time. A
6//! spec whose provider was never registered would otherwise resolve to
7//! `None` and be dropped **silently** — for a guard that means every route
8//! quietly loses its fail-secure net. Each `use_*_global` builder therefore
9//! attaches an [`HttpBootCheck`] that re-resolves its specs at configure
10//! time and fails boot with the offending type names, the same posture as
11//! the access graph (a wiring error is a boot error, never a runtime
12//! surprise).
13
14use nest_rs_core::Container;
15
16type CheckFn = Box<dyn Fn(&Container) -> Result<(), String> + Send + Sync>;
17
18/// A boot-time check the HTTP transport runs at the start of `configure`.
19/// Returning `Err(message)` aborts boot with that message.
20pub struct HttpBootCheck(CheckFn);
21
22impl HttpBootCheck {
23 pub fn new<F>(check: F) -> Self
24 where
25 F: Fn(&Container) -> Result<(), String> + Send + Sync + 'static,
26 {
27 Self(Box::new(check))
28 }
29
30 pub fn run(&self, container: &Container) -> Result<(), String> {
31 (self.0)(container)
32 }
33}
34
35/// Marker provided by `use_guards_global` when at least one global guard is
36/// registered. The transport reads it (it cannot see the `Guard` trait or
37/// `GuardSpecs`) to decide whether an unguardable endpoint — an imperative
38/// `mount(...)` the transport can neither shape nor introspect — is a
39/// fail-secure violation.
40pub struct GlobalGuardsActive;