photon_backend/delivery_mode.rs
1//! Topic delivery mode and virtual shard configuration.
2
3/// How publishes on a topic are routed to subscribers.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5pub enum DeliveryMode {
6 /// Every matching subscriber receives every event (default).
7 #[default]
8 Broadcast,
9 /// Events routed to virtual shards; one consumer group member per shard.
10 ConsumerGroup,
11}
12
13impl std::str::FromStr for DeliveryMode {
14 type Err = ();
15
16 /// Parse `"broadcast"`, `"group"`, or `"consumer_group"`.
17 fn from_str(s: &str) -> Result<Self, Self::Err> {
18 match s {
19 "broadcast" => Ok(Self::Broadcast),
20 "group" | "consumer_group" => Ok(Self::ConsumerGroup),
21 _ => Err(()),
22 }
23 }
24}
25
26/// Virtual shard settings for [`DeliveryMode::ConsumerGroup`] topics.
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct ShardConfig {
29 /// Number of virtual shards (`hash(routing_key) % shard_count`).
30 pub shard_count: u32,
31 /// JSON payload field used for routing when publish has no explicit partition key.
32 pub shard_by: Option<&'static str>,
33}
34
35impl ShardConfig {
36 /// Default shard count when topic macro omits `shards`.
37 pub const DEFAULT_SHARD_COUNT: u32 = 32;
38
39 /// Create shard config; `0` count is replaced with [`Self::DEFAULT_SHARD_COUNT`].
40 #[must_use]
41 pub const fn new(shard_count: u32, shard_by: Option<&'static str>) -> Self {
42 Self {
43 shard_count: if shard_count == 0 {
44 Self::DEFAULT_SHARD_COUNT
45 } else {
46 shard_count
47 },
48 shard_by,
49 }
50 }
51
52 /// Default shard count with no `shard_by` field.
53 #[must_use]
54 pub const fn default_count() -> Self {
55 Self::new(Self::DEFAULT_SHARD_COUNT, None)
56 }
57}