arcly_http/realtime/macros.rs
1//! Registry glue for the real-time macro layer.
2//!
3//! ## Where the procedural macros actually live
4//!
5//! Rust requires procedural (attribute) macros to be defined in a dedicated
6//! `proc-macro = true` crate — they cannot be authored in a normal library
7//! module. So the *implementations* of `#[Gateway]` and `#[Subscribe]` live in
8//! the `arcly-http-macros` crate; this module is the runtime landing zone for
9//! the code they emit, and the canonical place to understand that contract.
10//!
11//! ## What `#[Gateway("/path")]` expands to
12//!
13//! Placed on the gateway's handler `impl` block (the same ergonomic rule as
14//! `#[Controller]`, and for the same reason — `inventory::submit!` cannot be
15//! emitted from inside an `impl` body), it generates, at module scope:
16//!
17//! ```ignore
18//! // 1. A builder that wires the gateway's Inject<T> fields from the frozen
19//! // container (reusing the #[Injectable]-generated __arcly_build), leaks it
20//! // to &'static, and assembles the dispatch table from #[Subscribe] methods.
21//! fn __arcly_build_gateway_CHATGATEWAY(c: &'static FrozenDiContainer)
22//! -> &'static GatewayRuntime { /* ... */ }
23//!
24//! // 2. A descriptor + link-time registration.
25//! static __ARCLY_GATEWAY_CHATGATEWAY: GatewayDescriptor = GatewayDescriptor {
26//! name: "ChatGateway", path: "/chat-socket",
27//! build: __arcly_build_gateway_CHATGATEWAY,
28//! };
29//! inventory::submit! { &__ARCLY_GATEWAY_CHATGATEWAY }
30//! ```
31//!
32//! `#[Subscribe("event::name")]` is a *marker* consumed by the enclosing
33//! `#[Gateway]` walker — it adds one `event → handler` row to the dispatch
34//! table and is stripped before the impl is re-emitted.
35//!
36//! ## Aggregation
37//!
38//! `#[Module(..., gateways(ChatGateway))]` records the gateway's type name in
39//! its [`ModuleDescriptor`](crate::core::engine::ModuleDescriptor). At launch,
40//! `App` walks the reachable module DAG, and mounts each registered gateway
41//! whose name is in the reachable set — identical encapsulation to controllers.
42
43use crate::realtime::gateway::GatewayDescriptor;
44
45/// Iterate every link-time-registered gateway descriptor. Used by `App` during
46/// the launch mount pass.
47pub fn registered_gateways() -> impl Iterator<Item = &'static GatewayDescriptor> {
48 inventory::iter::<&'static GatewayDescriptor>
49 .into_iter()
50 .copied()
51}