mod encoding;
mod errors;
mod namespace;
mod typeid_suffix;
mod versions;
pub mod prelude {
pub use std::str::FromStr;
pub use uuid::{Uuid, Version};
pub use crate::errors::*;
pub use crate::namespace::NamespaceId;
pub use crate::typeid_suffix::TypeIdSuffix;
pub use crate::versions::*;
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use proptest::prelude::*;
use uuid::{Uuid, Version};
use crate::prelude::*;
#[test]
fn test_typeid_suffix_default() {
let suffix = TypeIdSuffix::default();
let uuid: Uuid = suffix.into();
assert_eq!(uuid.get_version(), Some(Version::SortRand));
}
#[test]
fn test_typeid_suffix_explicit_version() {
let _suffix = TypeIdSuffix::new::<V4>();
}
prop_compose! {
fn arbitrary_uuidv7()(timestamp in 0..=0xFFFF_FFFF_FFFF_FFFFu64, counter in 0..0x3FFFu16) -> Uuid {
let mut bytes = [0u8; 16];
bytes[0..8].copy_from_slice(×tamp.to_be_bytes());
bytes[8..10].copy_from_slice(&counter.to_be_bytes());
bytes[6] = (bytes[6] & 0x0F) | 0x70; bytes[8] = (bytes[8] & 0x3F) | 0x80; Uuid::from_bytes(bytes)
}
}
prop_compose! {
fn arbitrary_uuid_other()(version in 1u8..=5u8, bytes in proptest::array::uniform16(any::<u8>())) -> Uuid {
let mut uuid_bytes = bytes;
uuid_bytes[6] = (uuid_bytes[6] & 0x0F) | (version << 4); uuid_bytes[8] = (uuid_bytes[8] & 0x3F) | 0x80; Uuid::from_bytes(uuid_bytes)
}
}
#[cfg(test)]
#[cfg(feature = "serde")]
mod serde_tests {
use super::*;
#[test]
fn test_typeid_suffix_serialize() {
let suffix = TypeIdSuffix::default();
let serialized = serde_json::to_string(&suffix).unwrap();
assert!(serialized.starts_with('"') && serialized.ends_with('"'));
assert_eq!(serialized.len(), 28); }
#[test]
fn test_typeid_suffix_deserialize() {
let suffix = TypeIdSuffix::default();
let serialized = serde_json::to_string(&suffix).unwrap();
let deserialized: TypeIdSuffix = serde_json::from_str(&serialized).unwrap();
assert_eq!(suffix, deserialized);
}
#[test]
fn test_typeid_suffix_deserialize_error() {
let result = serde_json::from_str::<TypeIdSuffix>("\"invalid_suffix\"");
assert!(result.is_err());
}
}
proptest! {
#[test]
fn test_uuidv7_roundtrip(uuid in arbitrary_uuidv7()) {
let suffix: TypeIdSuffix = uuid.into();
let suffix_str = suffix.to_uuid().to_string();
let v7_uuid = Uuid::from_str(&suffix_str).unwrap();
let decoded: Uuid = v7_uuid;
prop_assert_eq!(v7_uuid, decoded);
prop_assert_eq!(suffix.len(), 26);
}
#[test]
fn test_uuid_other_roundtrip(uuid in arbitrary_uuid_other()) {
let suffix: TypeIdSuffix = uuid.into();
let v4_uuid = Uuid::from_str(suffix.to_uuid().to_string().as_str()).unwrap();
let decoded: Uuid = v4_uuid;
prop_assert_eq!(v4_uuid, decoded);
prop_assert_eq!(suffix.len(), 26);
}
#[test]
fn test_uuidv7_fromstr(uuid in arbitrary_uuid_other()) {
let suffix: TypeIdSuffix = uuid.into();
let from_str = TypeIdSuffix::from_str(&suffix).unwrap();
prop_assert_eq!(suffix, from_str);
}
#[test]
fn test_uuid_other_fromstr(uuid in arbitrary_uuid_other()) {
let suffix: TypeIdSuffix = uuid.into();
let from_str = TypeIdSuffix::from_str(&suffix).unwrap();
prop_assert_eq!(suffix, from_str);
}
#[test]
fn test_invalid_suffix(s in "[0-9a-zA-Z]{26}") {
if s.as_bytes()[0] > b'7' {
prop_assert!(TypeIdSuffix::from_str(&s).is_err());
prop_assert!(TypeIdSuffix::from_str(&s).is_err());
}
}
}
}