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}