Compare commits
No commits in common. "3329e01c2cf049f9f085c3e3f262a63880765490" and "dd6b28a0397eb5668e1c13c6be940ad17e1c9333" have entirely different histories.
3329e01c2c
...
dd6b28a039
4 changed files with 18 additions and 47 deletions
|
@ -1,8 +1,8 @@
|
||||||
[package]
|
[package]
|
||||||
name = "julid-rs"
|
name = "julid-rs"
|
||||||
# 1.61803398874989484
|
# 1.61803398874989484
|
||||||
#---------------^
|
#--------------^
|
||||||
version = "1.6.180339887498"
|
version = "1.6.18033988749"
|
||||||
authors = ["Joe Ardent <code@ardent.nebcorp.com>"]
|
authors = ["Joe Ardent <code@ardent.nebcorp.com>"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
keywords = ["ulid", "sqlite", "julid", "uuid", "guid"]
|
keywords = ["ulid", "sqlite", "julid", "uuid", "guid"]
|
||||||
|
@ -41,7 +41,7 @@ uuid = { version = "1.17", default-features = false, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
divan = "0.1"
|
divan = "0.1"
|
||||||
uuid = { version = "1", default-features = false, features = ["v7", "v4"] }
|
uuid = { version = "1", default-features = false, features = ["v7"] }
|
||||||
julid-rs = { path = ".", features = ["uuid"] }
|
julid-rs = { path = ".", features = ["uuid"] }
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
1.6180339887498
|
1.618033988749
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl fmt::Display for DecodeError {
|
||||||
DecodeError::InvalidLength(len) => format!("invalid length: {len}"),
|
DecodeError::InvalidLength(len) => format!("invalid length: {len}"),
|
||||||
DecodeError::InvalidChar(c) => format!("invalid character: {c}"),
|
DecodeError::InvalidChar(c) => format!("invalid character: {c}"),
|
||||||
};
|
};
|
||||||
write!(f, "{text}")
|
write!(f, "{}", text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
55
src/uuid.rs
55
src/uuid.rs
|
@ -2,7 +2,7 @@ use std::fmt;
|
||||||
|
|
||||||
use uuid::{Uuid, Variant};
|
use uuid::{Uuid, Variant};
|
||||||
|
|
||||||
use crate::{Julid, COUNTER_BITS};
|
use crate::Julid;
|
||||||
|
|
||||||
impl Julid {
|
impl Julid {
|
||||||
/// Convert to UUIDv7, possibly losing counter bits and altering the top
|
/// Convert to UUIDv7, possibly losing counter bits and altering the top
|
||||||
|
@ -40,32 +40,11 @@ impl Julid {
|
||||||
return Err(UuidError::UnsupportedVariant(var));
|
return Err(UuidError::UnsupportedVariant(var));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (hi, lo) = id.as_u64_pair();
|
Ok(id.as_u64_pair().into())
|
||||||
// zero out the high bits of the counter, which are "7" (0b0111) from the uuid
|
|
||||||
let mask = (1 << 12) - 1;
|
|
||||||
let counter = hi & mask;
|
|
||||||
let ts = hi >> COUNTER_BITS;
|
|
||||||
let hi = (ts << COUNTER_BITS) | counter;
|
|
||||||
|
|
||||||
Ok((hi, lo).into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Julid> for Uuid {
|
#[derive(Debug)]
|
||||||
fn from(value: Julid) -> Self {
|
|
||||||
value.as_uuid()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Uuid> for Julid {
|
|
||||||
type Error = UuidError;
|
|
||||||
|
|
||||||
fn try_from(value: Uuid) -> Result<Self, Self::Error> {
|
|
||||||
Julid::from_uuid(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
||||||
pub enum UuidError {
|
pub enum UuidError {
|
||||||
UnsupportedVersion(usize),
|
UnsupportedVersion(usize),
|
||||||
UnsupportedVariant(uuid::Variant),
|
UnsupportedVariant(uuid::Variant),
|
||||||
|
@ -85,9 +64,7 @@ impl fmt::Display for UuidError {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use uuid::Uuid;
|
use crate::Julid;
|
||||||
|
|
||||||
use crate::{uuid::UuidError, Julid};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn into_uuid() {
|
fn into_uuid() {
|
||||||
|
@ -101,23 +78,17 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn from_uuid() {
|
fn from_uuid() {
|
||||||
let j1 = Julid::new();
|
let j1 = Julid::new();
|
||||||
|
let u1 = j1.as_uuid();
|
||||||
|
let ju1 = Julid::from_uuid(u1).unwrap();
|
||||||
|
// casting a julid to a uuid alters the counter and entropy bits slightly, so
|
||||||
|
// the original julid and one derived from a uuid made from it won't be the
|
||||||
|
// same.
|
||||||
|
assert_ne!(j1, ju1);
|
||||||
|
|
||||||
let u1: Uuid = j1.into();
|
|
||||||
let ju1: Julid = u1.try_into().unwrap();
|
|
||||||
assert_eq!(j1.timestamp(), ju1.timestamp());
|
|
||||||
assert_eq!(j1.counter(), ju1.counter());
|
|
||||||
assert_eq!(j1.random() << 2, ju1.random() << 2);
|
|
||||||
// once we've converted to uuid and then back to julid, we've reached the fixed
|
|
||||||
// point
|
|
||||||
let u2 = ju1.as_uuid();
|
let u2 = ju1.as_uuid();
|
||||||
let ju2 = u2.try_into().unwrap();
|
let ju2 = Julid::from_uuid(u2).unwrap();
|
||||||
|
// but once we've made that alteration, we've reached the fixed point
|
||||||
assert_eq!(ju1, ju2);
|
assert_eq!(ju1, ju2);
|
||||||
}
|
assert_eq!(u1, u2);
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cant_even_from_uuid_non_v7() {
|
|
||||||
let u = uuid::Uuid::new_v4();
|
|
||||||
let jr: Result<Julid, UuidError> = u.try_into();
|
|
||||||
assert_eq!(jr, Err(UuidError::UnsupportedVersion(4)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue