use uuid::Uuid;
use super::Error;
pub fn new_v4() -> Uuid {
Uuid::new_v4()
}
pub fn now_v7() -> Uuid {
Uuid::now_v7()
}
pub fn to_time_epoch_ms(uuid: &Uuid) -> Result<i64, Error> {
if uuid.get_version_num() != 7 {
return Err(Error::FailExtractTimeNoUuidV7(*uuid));
}
let as_int = uuid.as_u128();
let ts_ms = (as_int >> 80) as i64;
Ok(ts_ms)
}
#[cfg(test)]
mod tests {
use std::time::SystemTime;
use uuid::Version;
use super::*;
type Result<T> = core::result::Result<T, Box<dyn std::error::Error>>;
#[test]
fn test_extra_uuid_new_v4_simple() -> Result<()> {
let uuid_v4 = new_v4();
assert_eq!(uuid_v4.get_version(), Some(Version::Random));
Ok(())
}
#[test]
fn test_extra_uuid_new_v7_simple() -> Result<()> {
let uuid_v7_1 = now_v7();
std::thread::sleep(std::time::Duration::from_micros(100)); let uuid_v7_2 = now_v7();
assert_eq!(uuid_v7_1.get_version(), Some(Version::SortRand));
assert_eq!(uuid_v7_2.get_version(), Some(Version::SortRand));
assert!(uuid_v7_1 < uuid_v7_2, "UUID {} should be less than UUID {}", uuid_v7_1, uuid_v7_2);
Ok(())
}
#[test]
fn test_extra_uuid_to_time_epoch_ms_ok() -> Result<()> {
let t0_ms = system_time_to_ms(SystemTime::now())?;
std::thread::sleep(std::time::Duration::from_millis(1));
let uuid_v7 = now_v7();
std::thread::sleep(std::time::Duration::from_millis(1));
let t1_ms = system_time_to_ms(SystemTime::now())?;
let extracted_ts_ms = to_time_epoch_ms(&uuid_v7)?;
assert!(
extracted_ts_ms >= t0_ms,
"Extracted timestamp {}ms should be greater than or equal to t0_ms {}ms. UUID: {}",
extracted_ts_ms,
t0_ms,
uuid_v7
);
assert!(
extracted_ts_ms <= t1_ms,
"Extracted timestamp {}ms should be less than or equal to t1_ms {}ms. UUID: {}",
extracted_ts_ms,
t1_ms,
uuid_v7
);
Ok(())
}
#[test]
fn test_extra_uuid_to_time_epoch_ms_err_not_v7() -> Result<()> {
let uuid_v4 = new_v4();
let result = to_time_epoch_ms(&uuid_v4);
match result {
Err(Error::FailExtractTimeNoUuidV7(id)) => {
assert_eq!(id, uuid_v4, "The UUID in the error should match the input UUID.");
}
Ok(ts) => {
return Err(
format!("Expected FailExtractTimeNoUuidV7 error for non-v7 UUID, but got Ok({}). UUID was: {}", ts, uuid_v4)
.into(),
);
}
Err(other_error) => {
return Err(
format!(
"Expected FailExtractTimeNoUuidV7 error, but got a different error: {:?}. UUID was: {}",
other_error, uuid_v4
)
.into(),
);
}
}
Ok(())
}
fn system_time_to_ms(st: SystemTime) -> Result<i64> {
Ok(
st.duration_since(SystemTime::UNIX_EPOCH)
.map_err(|e| format!("Failed to get duration since UNIX_EPOCH: {}", e))?
.as_millis() as i64,
)
}
}