use crate::{Metadata, MetadataEntry, MetadataFlags, MetadataValue};
pub const RETRY_SUPPORT_METADATA_KEY: &str = "vox-retry-support";
pub const OPERATION_ID_METADATA_KEY: &str = "vox-operation-id";
pub const CHANNEL_RETRY_MODE_METADATA_KEY: &str = "vox-channel-retry-mode";
pub const RETRY_SUPPORT_VERSION: u64 = 1;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum ChannelRetryMode {
None = 0,
NonIdem = 1,
Idem = 2,
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct OperationId(pub u64);
impl std::fmt::Display for OperationId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Debug)]
pub struct PostcardPayload(pub Vec<u8>);
impl PostcardPayload {
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
pub fn append_retry_support_metadata(metadata: &mut Metadata<'_>) {
if metadata_supports_retry(metadata) {
return;
}
metadata.push(MetadataEntry {
key: RETRY_SUPPORT_METADATA_KEY.into(),
value: MetadataValue::U64(RETRY_SUPPORT_VERSION),
flags: MetadataFlags::NONE,
});
}
pub fn metadata_supports_retry(metadata: &[MetadataEntry<'_>]) -> bool {
metadata.iter().any(|entry| {
entry.key == RETRY_SUPPORT_METADATA_KEY
&& matches!(&entry.value, MetadataValue::U64(v) if *v == RETRY_SUPPORT_VERSION)
})
}
pub fn metadata_operation_id(metadata: &[MetadataEntry<'_>]) -> Option<OperationId> {
metadata.iter().find_map(|entry| {
if entry.key != OPERATION_ID_METADATA_KEY {
return None;
}
match &entry.value {
MetadataValue::U64(value) => Some(OperationId(*value)),
_ => None,
}
})
}
pub fn ensure_operation_id(metadata: &mut Metadata<'_>, operation_id: OperationId) {
if metadata_operation_id(metadata).is_some() {
return;
}
metadata.push(MetadataEntry {
key: OPERATION_ID_METADATA_KEY.into(),
value: MetadataValue::U64(operation_id.0),
flags: MetadataFlags::NONE,
});
}
pub fn metadata_channel_retry_mode(metadata: &[MetadataEntry<'_>]) -> ChannelRetryMode {
metadata
.iter()
.find_map(|entry| {
if entry.key != CHANNEL_RETRY_MODE_METADATA_KEY {
return None;
}
match &entry.value {
MetadataValue::U64(1) => Some(ChannelRetryMode::NonIdem),
MetadataValue::U64(2) => Some(ChannelRetryMode::Idem),
_ => Some(ChannelRetryMode::None),
}
})
.unwrap_or(ChannelRetryMode::None)
}
pub fn ensure_channel_retry_mode(metadata: &mut Metadata<'_>, mode: ChannelRetryMode) {
if matches!(mode, ChannelRetryMode::None) {
return;
}
if metadata
.iter()
.any(|entry| entry.key == CHANNEL_RETRY_MODE_METADATA_KEY)
{
return;
}
metadata.push(MetadataEntry {
key: CHANNEL_RETRY_MODE_METADATA_KEY.into(),
value: MetadataValue::U64(mode as u64),
flags: MetadataFlags::NONE,
});
}