Update docs, tests, and improve conversion to UUIDs.
This commit is contained in:
parent
02b99ba010
commit
8bbad764c3
4 changed files with 27 additions and 15 deletions
|
@ -12,6 +12,9 @@ readme = "README.md"
|
|||
license-file = "LICENSE.md"
|
||||
repository = "https://git.kittencollective.com/nebkor/julid-rs"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
[features]
|
||||
default = ["serde", "sqlx"] # just the regular crate
|
||||
serde = ["dep:serde"]
|
||||
|
@ -51,6 +54,3 @@ harness = false
|
|||
[[bin]]
|
||||
name = "julid-gen"
|
||||
path = "src/bin/gen.rs"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
|
@ -32,7 +32,7 @@ Blog post: <https://proclamations.nebcorp-hias.com/sundries/presenting-julids/>
|
|||
|
||||
As of June of 2025, they can also be converted to and from [version 7
|
||||
UUIDs](https://www.ietf.org/rfc/rfc9562.html#name-uuid-version-7), though some precision in the
|
||||
intra-millisecond counter is lost when going to a UUID.
|
||||
intra-millisecond counter is lost when going to a UUID, via the `uuid` optional feature.
|
||||
|
||||
## A slightly deeper look
|
||||
|
||||
|
|
27
src/lib.rs
27
src/lib.rs
|
@ -2,18 +2,27 @@
|
|||
use sqlite_loadable::prelude::{c_char, c_uint, sqlite3, sqlite3_api_routines};
|
||||
|
||||
mod base32;
|
||||
|
||||
/// Contains the [`Julid`] type, which is publicly exported at the top level.
|
||||
pub mod julid;
|
||||
#[cfg(feature = "serde")]
|
||||
|
||||
/// Serialization into bytes, and deserialization from a variety of formats,
|
||||
/// with Serde (feature `serde` (default))
|
||||
#[cfg(feature = "serde")]
|
||||
pub mod serde;
|
||||
#[cfg(feature = "sqlx")]
|
||||
|
||||
/// Traits from the SQLx crate for getting Julids into and out of SQLite
|
||||
/// databases from normal Rust applications. (feature `sqlx` (default))
|
||||
#[cfg(feature = "sqlx")]
|
||||
pub mod sqlx;
|
||||
#[cfg(feature = "uuid")]
|
||||
|
||||
/// UUIDv7s are almost as good as Julids, and can be interconverted almost
|
||||
/// perfectly.
|
||||
/// perfectly. (feature `uuid` (non-default))
|
||||
///
|
||||
/// See the [`Julid::as_uuid`] and [`Julid::from_uuid`] methods for
|
||||
/// converting a Julid to a UUID and constructing a Julid from a UUID
|
||||
/// respectively.
|
||||
#[cfg(feature = "uuid")]
|
||||
pub mod uuid;
|
||||
|
||||
#[doc(inline)]
|
||||
|
@ -21,13 +30,13 @@ pub use base32::DecodeError;
|
|||
#[doc(inline)]
|
||||
pub use julid::Julid;
|
||||
|
||||
/// The number of bits in a Julid's time portion
|
||||
/// The number of bits in a Julid's millisecond timestamp (48)
|
||||
pub const TIME_BITS: u8 = 48;
|
||||
/// The number of bits in the monotonic counter for intra-millisecond IDs
|
||||
/// The number of bits in the monotonic counter for intra-millisecond IDs (16)
|
||||
pub const COUNTER_BITS: u8 = 16;
|
||||
/// The number of random bits + bits in the monotonic counter
|
||||
/// The number of random bits + bits in the monotonic counter (80)
|
||||
pub const UNIQUE_BITS: u8 = 80;
|
||||
/// The number of fully random bits
|
||||
/// The number of fully random bits (64)
|
||||
pub const RANDOM_BITS: u8 = 64;
|
||||
|
||||
/// This `unsafe extern "C"` function is the main entry point into the loadable
|
||||
|
@ -52,7 +61,7 @@ pub unsafe extern "C" fn sqlite3_julid_init(
|
|||
}
|
||||
|
||||
/// The code for the SQLite plugin is kept in this module, and exposed via the
|
||||
/// `sqlite3_julid_init` function (feature `plugin`)
|
||||
/// [`sqlite3_julid_init`] function (feature `plugin` (non-default))
|
||||
#[cfg(feature = "plugin")]
|
||||
pub mod sqlite_plugin {
|
||||
use sqlite_loadable::{
|
||||
|
|
|
@ -13,7 +13,7 @@ impl Julid {
|
|||
/// means that some bits in the original Julid are overwritten with
|
||||
/// UUID-specific values, but only six bits in total are potentially
|
||||
/// altered.
|
||||
pub fn as_uuid(&self) -> Uuid {
|
||||
pub const fn as_uuid(&self) -> Uuid {
|
||||
let counter_mask = (1 << 12) - 1;
|
||||
let entropy_mask = (1 << 62) - 1;
|
||||
let timestamp = self.timestamp();
|
||||
|
@ -29,7 +29,9 @@ impl Julid {
|
|||
///
|
||||
/// UUIDv7s are very similar to Julids, but use 12 bits for a monotonic
|
||||
/// counter instead of 16, and only 62 bits of entropy vs Julids' 64.
|
||||
/// Therefore, no bits need to be altered when converting to a Julid.
|
||||
/// Therefore, no bits technically need to be altered when converting to a
|
||||
/// Julid, but we zero out the high bits of the counter where the UUID
|
||||
/// version was stored.
|
||||
pub fn from_uuid(id: Uuid) -> Result<Self, UuidError> {
|
||||
let ver = id.get_version_num();
|
||||
if ver != 7 {
|
||||
|
@ -107,6 +109,7 @@ mod test {
|
|||
assert_eq!(j1.timestamp(), ju1.timestamp());
|
||||
assert_eq!(j1.counter(), ju1.counter());
|
||||
assert_eq!(j1.random() << 2, ju1.random() << 2);
|
||||
assert_eq!(ju1.random() >> 62, 2);
|
||||
// once we've converted to uuid and then back to julid, we've reached the fixed
|
||||
// point
|
||||
let u2 = ju1.as_uuid();
|
||||
|
|
Loading…
Reference in a new issue