1pub mod sel;
2
3use std::num::NonZeroU16;
4
5pub mod sdr;
6
7use crate::{fmt::LogItem, log_vec, Loggable};
8
9#[derive(Debug, Clone, Copy, PartialEq)]
10pub struct Timestamp(u32);
11
12impl core::fmt::Display for Timestamp {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 if self.0 == 0 {
15 write!(f, "Unknown")
16 } else {
17 #[cfg(feature = "time")]
18 {
19 let timestamp = time::OffsetDateTime::from_unix_timestamp(self.0 as i64).unwrap();
20
21 let time = timestamp
22 .format(&time::format_description::well_known::Rfc3339)
23 .unwrap();
24
25 write!(f, "{}", time)
26 }
27
28 #[cfg(not(feature = "time"))]
29 write!(f, "{}", self.0)
30 }
31 }
32}
33
34impl From<u32> for Timestamp {
35 fn from(value: u32) -> Self {
36 Self(value)
37 }
38}
39
40#[derive(Debug, Clone)]
41pub struct AllocInfo {
42 pub num_alloc_units: Option<NonZeroU16>,
43 pub alloc_unit_size: Option<NonZeroU16>,
44 pub num_free_units: u16,
45 pub largest_free_blk: u16,
46 pub max_record_size: u8,
47}
48
49impl AllocInfo {
50 pub fn parse(data: &[u8]) -> Option<Self> {
51 if data.len() < 8 {
52 return None;
53 }
54
55 let num_alloc_units = NonZeroU16::new(u16::from_le_bytes([data[0], data[1]]));
56 let alloc_unit_size = NonZeroU16::new(u16::from_le_bytes([data[2], data[3]]));
57 let num_free_units = u16::from_le_bytes([data[4], data[5]]);
58 let largest_free_blk = u16::from_le_bytes([data[6], data[7]]);
59 let max_record_size = data[8];
60
61 Some(Self {
62 num_alloc_units,
63 alloc_unit_size,
64 num_free_units,
65 largest_free_blk,
66 max_record_size,
67 })
68 }
69}
70
71impl Loggable for AllocInfo {
72 fn as_log(&self) -> Vec<LogItem> {
73 let unspecified_if_zero = |v: Option<NonZeroU16>| {
74 if let Some(v) = v {
75 format!("{}", v.get())
76 } else {
77 "Unspecified".into()
78 }
79 };
80
81 let num_alloc_units = unspecified_if_zero(self.num_alloc_units);
82 let alloc_unit_size = unspecified_if_zero(self.alloc_unit_size);
83
84 log_vec!(
85 (1, "# of units", num_alloc_units),
86 (1, "Unit size", alloc_unit_size),
87 (1, "# free units", self.num_free_units),
88 (1, "Largest free block", self.largest_free_blk),
89 (1, "Max record size", self.max_record_size),
90 )
91 }
92}