use crate::codec::{decode_sortable64, read_uint48_be, to_hex};
use crate::error::OrionIdError;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ParsedOrionId {
pub id: String,
pub bytes: [u8; crate::alphabet::ID_SIZE_BYTES],
pub unix_ms: u128,
pub relative_ms: u128,
pub fraction4096: u16,
pub counter: u32,
pub random_hex: String,
}
pub fn parse(id: &str, epoch_ms: u128) -> Result<ParsedOrionId, OrionIdError> {
let bytes = decode_sortable64(id)?;
let relative_ms = read_uint48_be(&bytes, 0);
let fraction4096 = (u16::from(bytes[6]) << 4) | (u16::from(bytes[7]) >> 4);
let counter =
(u32::from(bytes[7] & 0x0f) << 16) | (u32::from(bytes[8]) << 8) | u32::from(bytes[9]);
let unix_ms = relative_ms.saturating_add(epoch_ms);
let random_hex = to_hex(&bytes[10..]);
Ok(ParsedOrionId {
id: id.to_string(),
bytes,
unix_ms,
relative_ms,
fraction4096,
counter,
random_hex,
})
}
pub fn is_valid(id: &str) -> bool {
decode_sortable64(id).is_ok()
}