use std::time::{SystemTime, UNIX_EPOCH};
mod errors;
mod hex;
mod monotonic_refs;
mod nano64;
mod nano64_encrypted;
pub use errors::*;
pub use hex::*;
pub use nano64::*;
pub use nano64_encrypted::*;
pub const IV_LENGTH: usize = 12;
pub const PAYLOAD_LENGTH: usize = IV_LENGTH + 8 + 16;
pub const TIMESTAMP_BITS: u64 = 44;
pub const RANDOM_BITS: u64 = 20;
pub(crate) const TIMESTAMP_SHIFT: u64 = RANDOM_BITS;
pub(crate) const TIMESTAMP_MASK: u64 = (1 << TIMESTAMP_BITS) - 1;
pub(crate) const RANDOM_MASK: u64 = (1 << RANDOM_BITS) - 1;
pub(crate) const MAX_TIMESTAMP: u64 = TIMESTAMP_MASK;
pub fn compare(a: &Nano64, b: &Nano64) -> i64 {
if a.value < b.value {
return -1;
} else if a.value > b.value {
return 1;
}
return 0;
}
pub type RandomNumberGeneratorImpl = fn(bits: u32) -> Result<u32, Nano64Error>;
pub type Clock = fn() -> u64;
fn time_now_since_epoch_ms() -> u64 {
return SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
}
fn default_rng(bits: u32) -> Result<u32, Nano64Error> {
if bits == 0 || bits > 32 {
return Err(Nano64Error::Error(format!("bits must be 1-32, got {bits}")));
}
let mut buf = [0u8; 4];
rand::fill(&mut buf);
let mut val = u32::from_be_bytes(buf);
if bits < 32 {
val &= (1u32 << bits) - 1;
}
Ok(val)
}