#[cfg(feature = "chrono")]
#[inline]
pub fn decode_timestamp(ts: i64) -> Timestamp {
#[cfg(target_family = "wasm")]
const PRECISION: i64 = 1_000;
#[cfg(not(target_family = "wasm"))]
const PRECISION: i64 = 1_000_000;
let s = ts / PRECISION;
let ns = (ts.rem_euclid(PRECISION) * (1_000_000_000 / PRECISION)) as u32;
Timestamp { s, ns }
}
#[cfg(feature = "chrono")]
pub struct Timestamp {
pub s: i64,
pub ns: u32,
}
#[cfg(feature = "uuid")]
pub(crate) const UUID_SIZE_IN_BYTES: usize = 16;
#[cfg(feature = "uuid")]
#[inline]
fn decode_uuid_ref(id: &[u8]) -> uuid::Uuid {
uuid::Uuid::from_bytes(
*<&[u8] as std::convert::TryInto<&[u8; UUID_SIZE_IN_BYTES]>>::try_into(id)
.expect("invalid uuid slice"),
)
}
#[cfg(feature = "uuid")]
#[inline]
pub fn decode_uuid(id: Vec<u8>) -> uuid::Uuid {
decode_uuid_ref(id.as_slice())
}
#[cfg(test)]
#[cfg(feature = "chrono")]
mod tests {
#[test]
fn test_decode_timestamp_preserves_seconds_and_nanoseconds() {
#[cfg(not(target_family = "wasm"))]
{
let input: i64 = 3_496_567_123;
let super::Timestamp { s, ns } = super::decode_timestamp(input);
assert_eq!(s, 3_496);
assert_eq!(ns, 567_123_000);
}
#[cfg(target_family = "wasm")]
{
let input: i64 = 3_496_567;
let super::Timestamp { s, ns } = super::decode_timestamp(input);
assert_eq!(s, 3_496);
assert_eq!(ns, 567_000_000);
}
let super::Timestamp { s, ns } = super::decode_timestamp(-1);
assert_eq!(s, 0);
#[cfg(not(target_family = "wasm"))]
assert_eq!(ns, 999_999_000);
#[cfg(target_family = "wasm")]
assert_eq!(ns, 999_000_000);
}
}
#[cfg(test)]
#[cfg(feature = "uuid")]
mod uuid_tests {
#[test]
fn test_decode_uuid_validates_the_input_length() {
let bytes = [7_u8; super::UUID_SIZE_IN_BYTES];
assert_eq!(super::decode_uuid(bytes.to_vec()).as_bytes(), &bytes);
let result = std::panic::catch_unwind(|| super::decode_uuid(vec![7; 15]));
assert!(result.is_err());
}
}