Skip to main content

photon_backend/
descriptor.rs

1//! Topic descriptor for auto-registration.
2
3use serde_json::Value;
4
5use crate::delivery_mode::{DeliveryMode, ShardConfig};
6
7/// Descriptor for a registered topic (from `#[photon::topic]` macro).
8///
9/// Used for runtime lookup and schema metadata.
10#[derive(Debug, Clone)]
11pub struct TopicDescriptor {
12    /// Stable topic name (e.g., "user.notifications").
13    pub topic_name: &'static str,
14    /// Optional key field name.
15    pub keyed_by: Option<&'static str>,
16    /// Reserved JSON schema metadata placeholder.
17    ///
18    /// Currently always `"{}"` from `#[photon::topic]`. **Not validated** at publish time;
19    /// do not infer schema enforcement from this field.
20    pub schema_json: &'static str,
21    /// Publish routing mode (broadcast default).
22    pub delivery: DeliveryMode,
23    /// Virtual shard settings when [`DeliveryMode::ConsumerGroup`].
24    pub shard_config: Option<ShardConfig>,
25}
26
27impl TopicDescriptor {
28    /// Create a broadcast topic descriptor (default delivery mode).
29    #[must_use]
30    pub const fn new(
31        topic_name: &'static str,
32        keyed_by: Option<&'static str>,
33        schema_json: &'static str,
34    ) -> Self {
35        Self {
36            topic_name,
37            keyed_by,
38            schema_json,
39            delivery: DeliveryMode::Broadcast,
40            shard_config: None,
41        }
42    }
43
44    /// Create a consumer-group topic with virtual shard routing.
45    #[must_use]
46    pub const fn group(
47        topic_name: &'static str,
48        shard_count: u32,
49        shard_by: Option<&'static str>,
50        schema_json: &'static str,
51    ) -> Self {
52        Self {
53            topic_name,
54            keyed_by: None,
55            schema_json,
56            delivery: DeliveryMode::ConsumerGroup,
57            shard_config: Some(ShardConfig::new(shard_count, shard_by)),
58        }
59    }
60
61    /// Whether publishes route to virtual shard streams.
62    #[must_use]
63    pub fn is_consumer_group(&self) -> bool {
64        self.delivery == DeliveryMode::ConsumerGroup
65    }
66
67    /// Get schema as parsed JSON.
68    #[must_use]
69    pub fn schema_value(&self) -> Option<Value> {
70        serde_json::from_str(self.schema_json).ok()
71    }
72}
73
74// Register with inventory for auto-collection
75crate::inventory::collect!(TopicDescriptor);
76
77impl quark::Registrable for TopicDescriptor {
78    fn registry_key(&self) -> &str {
79        self.topic_name
80    }
81}