use schemars::JsonSchema;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use zerocopy::{big_endian, FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned, U16};
mod slot_counter;
pub use slot_counter::{InvalidSlotNumber, SlotCounter, SlotEpoch, SlotNumber};
#[derive(
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
FromBytes,
IntoBytes,
Unaligned,
KnownLayout,
Immutable,
)]
#[repr(transparent)]
pub struct ShortAddress(pub big_endian::U16);
impl std::fmt::Debug for ShortAddress {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_tuple("ShortAddress")
.field(&format_args!("{:#06X}", u16::from(self.0)))
.finish()
}
}
impl std::fmt::Display for ShortAddress {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:#06X}", u16::from(self.0))
}
}
#[derive(
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
Serialize,
Deserialize,
JsonSchema,
FromBytes,
IntoBytes,
Unaligned,
KnownLayout,
Immutable,
)]
#[repr(transparent)]
pub struct LongAddress(pub [u8; 8]);
impl LongAddress {
pub fn barcode(&self) -> crate::barcode::Barcode {
self.into()
}
}
impl std::fmt::Debug for LongAddress {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_tuple("LongAddress")
.field(&format_args!(
"[{:#04X}, {:#04X}, {:#04X}, {:#04X}, {:#04X}, {:#04X}, {:#04X}, {:#04X}]",
self.0[0],
self.0[1],
self.0[2],
self.0[3],
self.0[4],
self.0[5],
self.0[6],
self.0[7],
))
.finish()
}
}
impl std::fmt::Display for LongAddress {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7],
)
}
}
#[derive(Copy, Clone, Eq, PartialEq, FromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
#[repr(transparent)]
pub struct DSN(pub u8);
impl std::ops::Add<u8> for DSN {
type Output = Self;
fn add(self, rhs: u8) -> Self::Output {
Self(self.0.wrapping_add(rhs))
}
}
impl std::fmt::Debug for DSN {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_tuple("DSN")
.field(&format_args!("{:#04X}", self.0))
.finish()
}
}
impl std::fmt::Display for DSN {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:#04X}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn long_address_fmt() {
assert_eq!(
format!(
"{:?}",
&LongAddress([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
),
"LongAddress([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])"
);
assert_eq!(
format!(
"{}",
&LongAddress([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])
),
"01:02:03:04:05:06:07:08"
);
}
#[test]
fn short_address_fmt() {
assert_eq!(
format!("{:?}", &ShortAddress(0x1234.into())),
"ShortAddress(0x1234)",
);
assert_eq!(format!("{}", &ShortAddress(0x1234.into())), "0x1234",);
}
#[test]
fn dsn_fmt() {
assert_eq!(format!("{:?}", &DSN(0x12)), "DSN(0x12)",);
assert_eq!(format!("{}", &DSN(0x12)), "0x12",);
}
}