Skip to main content

photon_backend/
handler_ctx.rs

1//! Delivery metadata injectable into `#[photon::subscribe]` handlers (v2).
2
3/// Delivery metadata for a single handler invocation.
4///
5/// Inject as a trailing parameter on a `#[photon::subscribe]` handler (after actor and
6/// payload), alone or alongside `&Event`:
7///
8/// ```ignore
9/// #[photon::subscribe(topic = "orders", durable = "worker")]
10/// async fn on_order(
11///     _actor: Box<dyn Actor>,
12///     order: OrderPlaced,
13///     ctx: HandlerCtx<'_>,
14/// ) -> photon::Result<()> {
15///     tracing::info!(event_id = %ctx.event_id, seq = ctx.seq, "handling");
16///     Ok(())
17/// }
18/// ```
19///
20/// Values borrow from the transport [`crate::models::Event`] passed to the generated
21/// invoker for the duration of the handler future.
22#[derive(Debug, Clone, Copy)]
23pub struct HandlerCtx<'a> {
24    /// Unique event ID (UUID string from the transport event).
25    pub event_id: &'a str,
26    /// Topic name the event was published on.
27    pub topic_name: &'a str,
28    /// Partition / routing key when the topic is keyed.
29    pub topic_key: Option<&'a str>,
30    /// Monotonic sequence number for this topic (and key, when keyed).
31    pub seq: i64,
32}
33
34impl<'a> HandlerCtx<'a> {
35    /// Build from a transport [`crate::models::Event`].
36    #[must_use]
37    pub fn from_event(event: &'a crate::models::Event) -> Self {
38        Self {
39            event_id: &event.event_id,
40            topic_name: &event.topic_name,
41            topic_key: event.topic_key.as_deref(),
42            seq: event.seq,
43        }
44    }
45}