#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Durability {
Durable = 0x01,
Buffered = 0x03,
}
#[allow(non_upper_case_globals)]
impl Durability {
#[deprecated(since = "2.0.0", note = "renamed to `Durable`")]
pub const Sync: Self = Self::Durable;
#[deprecated(
since = "2.0.0",
note = "`Batched` was always identical to `Sync`; use `Durable`"
)]
pub const Batched: Self = Self::Durable;
}
impl From<Durability> for u8 {
fn from(d: Durability) -> u8 {
d as u8
}
}
impl std::fmt::Display for Durability {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Durability::Durable => "durable",
Durability::Buffered => "buffered",
};
write!(f, "{s}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct UnknownDurability(pub u8);
impl std::fmt::Display for UnknownDurability {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "unknown durability byte: {:#04x}", self.0)
}
}
impl std::error::Error for UnknownDurability {}
impl TryFrom<u8> for Durability {
type Error = UnknownDurability;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0x01 | 0x02 => Ok(Durability::Durable),
0x03 => Ok(Durability::Buffered),
v => Err(UnknownDurability(v)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wire_values_are_frozen() {
assert_eq!(Durability::Durable as u8, 0x01);
assert_eq!(Durability::Buffered as u8, 0x03);
}
#[test]
fn legacy_batched_byte_still_decodes_to_durable() {
assert_eq!(Durability::try_from(0x02).unwrap(), Durability::Durable);
}
#[test]
fn encoder_never_emits_the_retired_byte() {
assert_eq!(u8::from(Durability::Durable), 0x01);
assert_ne!(u8::from(Durability::Durable), 0x02);
}
#[test]
fn unknown_bytes_are_still_rejected() {
assert!(Durability::try_from(0x00).is_err());
assert!(Durability::try_from(0x04).is_err());
assert_eq!(
Durability::try_from(0x7f).unwrap_err(),
UnknownDurability(0x7f)
);
}
#[test]
fn deprecated_aliases_resolve_to_durable() {
#![allow(deprecated)]
assert_eq!(Durability::Sync, Durability::Durable);
assert_eq!(Durability::Batched, Durability::Durable);
}
#[test]
fn display_matches_the_metric_label() {
assert_eq!(Durability::Durable.to_string(), "durable");
assert_eq!(Durability::Buffered.to_string(), "buffered");
}
}