use super::Bytes;
use crate::term::internal::HpoTermInternal;
use crate::HpoError;
pub(crate) fn from_bytes_v1(bytes: Bytes) -> Result<HpoTermInternal, HpoError> {
if bytes.len() < 4 + 4 + 1 {
return Err(HpoError::ParseBinaryError);
}
let total_len = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
let id = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
let name_len = bytes[8] as usize;
if bytes.len() < 4 + 4 + 1 + name_len {
return Err(HpoError::ParseBinaryError);
}
let Ok(name) = String::from_utf8(bytes[9..total_len as usize].to_vec()) else {
return Err(HpoError::ParseBinaryError);
};
Ok(HpoTermInternal::new(name, id.into()))
}
pub(crate) fn from_bytes_v2(bytes: Bytes) -> Result<HpoTermInternal, HpoError> {
if bytes.len() < 14 {
return Err(HpoError::ParseBinaryError);
}
let id = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
let name_len = bytes[8] as usize;
if bytes.len() < 14 + name_len {
return Err(HpoError::ParseBinaryError);
}
let Ok(name) = String::from_utf8(bytes[9..9 + name_len].to_vec()) else {
return Err(HpoError::ParseBinaryError);
};
let mut term = HpoTermInternal::new(name, id.into());
if bytes[9 + name_len] & 1u8 == 1u8 {
*term.obsolete_mut() = true;
}
let offset = 10 + name_len;
let replacement_id = u32::from_be_bytes([
bytes[offset],
bytes[offset + 1],
bytes[offset + 2],
bytes[offset + 3],
]);
if replacement_id != 0 {
*term.replacement_mut() = Some(replacement_id.into());
}
Ok(term)
}