#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct PhonebookMetadata {
pub size: Option<u16>,
pub database_id: Option<[u8; 16]>,
pub primary_version: Option<[u8; 16]>,
pub secondary_version: Option<[u8; 16]>,
}
impl PhonebookMetadata {
pub(crate) fn parse(app_params: &[u8]) -> Self {
let mut out = Self::default();
for (tag, value) in tlv_entries(app_params) {
match tag {
0x08 => {
if let Ok(bytes) = value.try_into() {
out.size = Some(u16::from_be_bytes(bytes));
}
}
0x0A => out.primary_version = value.try_into().ok(),
0x0B => out.secondary_version = value.try_into().ok(),
0x0D => out.database_id = value.try_into().ok(),
_ => {}
}
}
out
}
}
fn tlv_entries(data: &[u8]) -> impl Iterator<Item = (u8, &[u8])> {
let mut rest = data;
std::iter::from_fn(move || {
let (&tag, after_tag) = rest.split_first()?;
let (&len, after_len) = after_tag.split_first()?;
let value = after_len.get(..usize::from(len))?;
rest = after_len.get(usize::from(len)..)?;
Some((tag, value))
})
}
#[cfg(test)]
mod tests;