use zerodds_cdr::{BufferReader, BufferWriter, DecodeError, EncodeError};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
#[repr(u32)]
pub enum DestinationOrderKind {
#[default]
ByReceptionTimestamp = 0,
BySourceTimestamp = 1,
}
impl DestinationOrderKind {
#[must_use]
pub const fn try_from_u32(v: u32) -> Option<Self> {
match v {
0 => Some(Self::ByReceptionTimestamp),
1 => Some(Self::BySourceTimestamp),
_ => None,
}
}
#[must_use]
pub const fn from_u32(v: u32) -> Self {
match v {
1 => Self::BySourceTimestamp,
_ => Self::ByReceptionTimestamp,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct DestinationOrderQosPolicy {
pub kind: DestinationOrderKind,
}
impl DestinationOrderQosPolicy {
pub fn encode_into(self, w: &mut BufferWriter) -> Result<(), EncodeError> {
w.write_u32(self.kind as u32)
}
pub fn decode_from(r: &mut BufferReader<'_>) -> Result<Self, DecodeError> {
let v = r.read_u32()?;
let kind = DestinationOrderKind::try_from_u32(v).ok_or(DecodeError::InvalidEnum {
kind: "DestinationOrderKind",
value: v,
})?;
Ok(Self { kind })
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
use zerodds_cdr::Endianness;
#[test]
fn default_by_reception() {
assert_eq!(
DestinationOrderQosPolicy::default().kind,
DestinationOrderKind::ByReceptionTimestamp
);
}
#[test]
fn kind_ordering() {
assert!(
DestinationOrderKind::ByReceptionTimestamp < DestinationOrderKind::BySourceTimestamp
);
}
#[test]
fn roundtrip() {
for kind in [
DestinationOrderKind::ByReceptionTimestamp,
DestinationOrderKind::BySourceTimestamp,
] {
let p = DestinationOrderQosPolicy { kind };
let mut w = BufferWriter::new(Endianness::Little);
p.encode_into(&mut w).unwrap();
let bytes = w.into_bytes();
let mut r = BufferReader::new(&bytes, Endianness::Little);
assert_eq!(DestinationOrderQosPolicy::decode_from(&mut r).unwrap(), p);
}
}
#[test]
fn try_from_u32_unknown_is_none() {
assert_eq!(DestinationOrderKind::try_from_u32(2), None);
assert_eq!(DestinationOrderKind::try_from_u32(u32::MAX), None);
}
#[test]
fn from_u32_forward_compatible() {
assert_eq!(
DestinationOrderKind::from_u32(0),
DestinationOrderKind::ByReceptionTimestamp
);
assert_eq!(
DestinationOrderKind::from_u32(1),
DestinationOrderKind::BySourceTimestamp
);
assert_eq!(
DestinationOrderKind::from_u32(42),
DestinationOrderKind::ByReceptionTimestamp
);
}
#[test]
fn decode_unknown_kind_errors() {
let mut w = BufferWriter::new(Endianness::Little);
w.write_u32(77).unwrap();
let bytes = w.into_bytes();
let mut r = BufferReader::new(&bytes, Endianness::Little);
let err = DestinationOrderQosPolicy::decode_from(&mut r).unwrap_err();
assert!(matches!(
err,
zerodds_cdr::DecodeError::InvalidEnum {
kind: "DestinationOrderKind",
value: 77
}
));
}
#[test]
fn decode_empty_buffer_errors() {
let bytes: [u8; 0] = [];
let mut r = BufferReader::new(&bytes, Endianness::Little);
assert!(DestinationOrderQosPolicy::decode_from(&mut r).is_err());
}
}