use crate::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ClockIdentity(pub [u8; 8]);
impl ClockIdentity {
#[must_use]
pub fn from_mac_address(addr: [u8; 6]) -> Self {
let mut this = Self([0; 8]);
this.0[0..6].copy_from_slice(&addr);
this
}
#[allow(
clippy::missing_panics_doc,
reason = "Clippy can't see copy_from_slice will never panic here"
)]
pub fn serialize(self, buffer: &mut [u8]) -> Result<(), Error> {
buffer
.get_mut(0..self.0.len())
.ok_or(Error::BufferTooShort)?
.copy_from_slice(&self.0);
Ok(())
}
#[allow(
clippy::missing_panics_doc,
reason = "Clippy can't tell the try_into will never fail"
)]
pub fn deserialize(buffer: &[u8]) -> Result<Self, Error> {
Ok(Self(
buffer
.get(0..8)
.ok_or(Error::BufferTooShort)?
.try_into()
.unwrap(),
))
}
}
#[cfg(feature = "std")]
impl core::fmt::Display for ClockIdentity {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
for (i, val) in self.0.iter().enumerate() {
if i != 0 {
write!(f, ":")?;
}
write!(f, "{val:02x}")?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn timestamp_wireformat() {
let representations = [(
[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08u8],
ClockIdentity([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]),
)];
for (byte_representation, object_representation) in representations {
let mut serialization_buffer = [0; 8];
object_representation
.serialize(&mut serialization_buffer)
.unwrap();
assert_eq!(serialization_buffer, byte_representation);
let deserialized_data = ClockIdentity::deserialize(&byte_representation).unwrap();
assert_eq!(deserialized_data, object_representation);
}
}
#[test]
fn from_mac() {
let mac = [1, 2, 3, 4, 5, 6];
let id = ClockIdentity::from_mac_address(mac);
assert_eq!(id, ClockIdentity([1, 2, 3, 4, 5, 6, 0, 0]));
}
}