vox_types/
retry_support.rs1use crate::{Metadata, MetadataEntry, MetadataFlags, MetadataValue};
2
3pub const RETRY_SUPPORT_METADATA_KEY: &str = "vox-retry-support";
4pub const OPERATION_ID_METADATA_KEY: &str = "vox-operation-id";
5pub const CHANNEL_RETRY_MODE_METADATA_KEY: &str = "vox-channel-retry-mode";
6pub const RETRY_SUPPORT_VERSION: u64 = 1;
7
8#[derive(Clone, Copy, PartialEq, Eq, Debug)]
9pub enum ChannelRetryMode {
10 None = 0,
11 NonIdem = 1,
12 Idem = 2,
13}
14
15#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
21pub struct OperationId(pub u64);
22
23impl std::fmt::Display for OperationId {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(f, "{}", self.0)
26 }
27}
28
29#[derive(Clone, Debug)]
34pub struct PostcardPayload(pub Vec<u8>);
35
36impl PostcardPayload {
37 pub fn as_bytes(&self) -> &[u8] {
38 &self.0
39 }
40}
41
42pub fn append_retry_support_metadata(metadata: &mut Metadata<'_>) {
43 if metadata_supports_retry(metadata) {
44 return;
45 }
46 metadata.push(MetadataEntry {
47 key: RETRY_SUPPORT_METADATA_KEY,
48 value: MetadataValue::U64(RETRY_SUPPORT_VERSION),
49 flags: MetadataFlags::NONE,
50 });
51}
52
53pub fn metadata_supports_retry(metadata: &[MetadataEntry<'_>]) -> bool {
54 metadata.iter().any(|entry| {
55 entry.key == RETRY_SUPPORT_METADATA_KEY
56 && matches!(entry.value, MetadataValue::U64(RETRY_SUPPORT_VERSION))
57 })
58}
59
60pub fn metadata_operation_id(metadata: &[MetadataEntry<'_>]) -> Option<OperationId> {
61 metadata.iter().find_map(|entry| {
62 if entry.key != OPERATION_ID_METADATA_KEY {
63 return None;
64 }
65 match entry.value {
66 MetadataValue::U64(value) => Some(OperationId(value)),
67 _ => None,
68 }
69 })
70}
71
72pub fn ensure_operation_id(metadata: &mut Metadata<'_>, operation_id: OperationId) {
73 if metadata_operation_id(metadata).is_some() {
74 return;
75 }
76 metadata.push(MetadataEntry {
77 key: OPERATION_ID_METADATA_KEY,
78 value: MetadataValue::U64(operation_id.0),
79 flags: MetadataFlags::NONE,
80 });
81}
82
83pub fn metadata_channel_retry_mode(metadata: &[MetadataEntry<'_>]) -> ChannelRetryMode {
84 metadata
85 .iter()
86 .find_map(|entry| {
87 if entry.key != CHANNEL_RETRY_MODE_METADATA_KEY {
88 return None;
89 }
90 match entry.value {
91 MetadataValue::U64(1) => Some(ChannelRetryMode::NonIdem),
92 MetadataValue::U64(2) => Some(ChannelRetryMode::Idem),
93 _ => Some(ChannelRetryMode::None),
94 }
95 })
96 .unwrap_or(ChannelRetryMode::None)
97}
98
99pub fn ensure_channel_retry_mode(metadata: &mut Metadata<'_>, mode: ChannelRetryMode) {
100 if matches!(mode, ChannelRetryMode::None) {
101 return;
102 }
103 if metadata
104 .iter()
105 .any(|entry| entry.key == CHANNEL_RETRY_MODE_METADATA_KEY)
106 {
107 return;
108 }
109 metadata.push(MetadataEntry {
110 key: CHANNEL_RETRY_MODE_METADATA_KEY,
111 value: MetadataValue::U64(mode as u64),
112 flags: MetadataFlags::NONE,
113 });
114}