Skip to content

Commit

Permalink
feat: Support typeid v0.3 spec
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnynotsolucky committed May 17, 2024
1 parent c8cf8c3 commit 10aa504
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 45 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ jobs:
with:
toolchain: stable
- run: cargo test --all-features
env:
RUSTFLAGS: "--cfg uuid_unstable"
msrv:
name: "Build / MSRV"
runs-on: ubuntu-latest
Expand All @@ -25,5 +23,3 @@ jobs:
with:
toolchain: 1.60.0
- run: cargo +1.60.0 build --all-features --manifest-path tests/smoke_test/Cargo.toml
env:
RUSTFLAGS: "--cfg uuid_unstable"
6 changes: 3 additions & 3 deletions strong_id/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ strong_id_macros = { version = "=0.3.0", path = "../strong_id_macros" }
bitvec = { version = "1", default-features = false, features = ["atomic", "alloc"] }
serde = { version = "1.0", optional = true, default-features = false, features = ["std"] }
thiserror = "1.0"
uuid = { version = "1.4", default-features = false, features = ["std"], optional = true }
uuid = { version = "1.6", default-features = false, features = ["std"], optional = true }

[dev-dependencies]
serde_json = "1.0"
Expand Down Expand Up @@ -58,6 +58,7 @@ uuid-v8 = ["strong_id_macros/uuid-v8", "uuid?/v8"]
# note: the TypeID spec does not allow delimited prefixes, so this should be used alongside
# `default-features = false`
typeid = [
"delimited",
"uuid",
"uuid-v7",
]
Expand All @@ -77,7 +78,6 @@ all = [
]

[package.metadata.docs.rs]
rustc-args = ["--cfg", "uuid_unstable"]
rustdoc-args = ["--cfg", "docsrs", "--cfg", "uuid_unstable"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-unknown-linux-gnu"]
all-features = true
37 changes: 23 additions & 14 deletions strong_id/src/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,25 @@ fn map_prefix<'p, I: Into<Prefix<'p>>>(prefix: I) -> Result<Prefix<'p>, Error> {
return Err(Error::PrefixTooLong(prefix.inner.len()));
}

for b in prefix.inner.as_bytes() {
if prefix.inner.is_empty() {
return Err(Error::PrefixExpected);
}

let underscore = b'_';
let bytes = prefix.inner.as_bytes();

if *bytes.first().unwrap() == underscore || *bytes.last().unwrap() == underscore {
return Err(Error::IncorrectPrefixCharacter(underscore as char));
}

for b in bytes {
if cfg!(feature = "delimited") && *b == b'_' {
continue;
} else if !b.is_ascii_lowercase() {
return Err(Error::IncorrectPrefixCharacter(*b as char));
}
}
if prefix.inner.is_empty() {
return Err(Error::PrefixExpected);
}

Ok(prefix)
}

Expand Down Expand Up @@ -322,7 +331,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
}
}

#[cfg(all(uuid_unstable, feature = "uuid-v6"))]
#[cfg(feature = "uuid-v6")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v6")))]
/// Create a new UUID-backed ID by generating a v6 UUID with a prefix
///
Expand All @@ -338,7 +347,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
})
}

#[cfg(all(uuid_unstable, feature = "uuid-v6"))]
#[cfg(feature = "uuid-v6")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v6")))]
/// Create a new UUID-backed ID by generating a v6 UUID without a prefix
///
Expand All @@ -350,7 +359,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
}
}

#[cfg(all(uuid_unstable, feature = "uuid-v6"))]
#[cfg(feature = "uuid-v6")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v6")))]
/// Create a new UUID-backed ID by generating a v6 UUID with a prefix
///
Expand All @@ -362,7 +371,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
})
}

#[cfg(all(uuid_unstable, feature = "uuid-v6"))]
#[cfg(feature = "uuid-v6")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v6")))]
/// Create a new UUID-backed ID by generating a v6 UUID without a prefix
///
Expand All @@ -374,7 +383,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
}
}

#[cfg(all(uuid_unstable, feature = "uuid-v7"))]
#[cfg(feature = "uuid-v7")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v7")))]
/// Create a new UUID-backed ID by generating a v7 UUID with a prefix
///
Expand All @@ -386,7 +395,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
})
}

#[cfg(all(uuid_unstable, feature = "uuid-v7"))]
#[cfg(feature = "uuid-v7")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v7")))]
/// Create a new UUID-backed ID by generating a v7 UUID without a prefix
///
Expand All @@ -398,7 +407,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
}
}

#[cfg(all(uuid_unstable, feature = "uuid-v7"))]
#[cfg(feature = "uuid-v7")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v7")))]
/// Create a new UUID-backed ID by generating a v7 UUID with a prefix
///
Expand All @@ -410,7 +419,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
})
}

#[cfg(all(uuid_unstable, feature = "uuid-v7"))]
#[cfg(feature = "uuid-v7")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v7")))]
/// Create a new UUID-backed ID by generating a v7 UUID without a prefix
///
Expand All @@ -422,7 +431,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
}
}

#[cfg(all(uuid_unstable, feature = "uuid-v8"))]
#[cfg(feature = "uuid-v8")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v8")))]
/// Create a new UUID-backed ID by generating a v7 UUID with a prefix
///
Expand All @@ -434,7 +443,7 @@ impl<'p> DynamicStrongId<'p, Uuid> {
})
}

#[cfg(all(uuid_unstable, feature = "uuid-v8"))]
#[cfg(feature = "uuid-v8")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v8")))]
/// Create a new UUID-backed ID by generating a v7 UUID without a prefix
///
Expand Down
22 changes: 11 additions & 11 deletions strong_id/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,24 +244,24 @@ pub trait StrongUuid {
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-v5")))]
fn new_v5(namespace: &Uuid, name: &[u8]) -> Self;

#[cfg(all(uuid_unstable, feature = "uuid-v6"))]
#[cfg_attr(docsrs, doc(cfg(all(uuid_unstable, feature = "uuid-v6"))))]
#[cfg(feature = "uuid-v6")]
#[cfg_attr(docsrs, doc(cfg(all(feature = "uuid-v6"))))]
fn new_v6(ts: uuid::Timestamp, node_id: &[u8; 6]) -> Self;

#[cfg(all(uuid_unstable, feature = "uuid-v6"))]
#[cfg_attr(docsrs, doc(cfg(all(uuid_unstable, feature = "uuid-v6"))))]
#[cfg(feature = "uuid-v6")]
#[cfg_attr(docsrs, doc(cfg(all(feature = "uuid-v6"))))]
fn now_v6(node_id: &[u8; 6]) -> Self;

#[cfg(all(uuid_unstable, feature = "uuid-v7"))]
#[cfg_attr(docsrs, doc(cfg(all(uuid_unstable, feature = "uuid-v7"))))]
#[cfg(feature = "uuid-v7")]
#[cfg_attr(docsrs, doc(cfg(all(feature = "uuid-v7"))))]
fn new_v7(ts: uuid::Timestamp) -> Self;

#[cfg(all(uuid_unstable, feature = "uuid-v7"))]
#[cfg_attr(docsrs, doc(cfg(all(uuid_unstable, feature = "uuid-v7"))))]
#[cfg(feature = "uuid-v7")]
#[cfg_attr(docsrs, doc(cfg(all(feature = "uuid-v7"))))]
fn now_v7() -> Self;

#[cfg(all(uuid_unstable, feature = "uuid-v8"))]
#[cfg_attr(docsrs, doc(cfg(all(uuid_unstable, feature = "uuid-v8"))))]
#[cfg(feature = "uuid-v8")]
#[cfg_attr(docsrs, doc(cfg(all(feature = "uuid-v8"))))]
fn new_v8(buf: [u8; 16]) -> Self;
}

Expand All @@ -280,7 +280,7 @@ macro_rules! impl_strong_uint {
if val.len() != encoded_len::<$t>() {
return Err(::strong_id::Error::InvalidLength(encoded_len::<$t>(), val.len()));
}

let mut out = [0; ::core::mem::size_of::<$t>()];
::strong_id::base32::decode(val.as_bytes(), &mut out)?;

Expand Down
17 changes: 12 additions & 5 deletions strong_id_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields, LitStr, Type};

fn assert_prefix_valid(prefix: &str) {
assert!(!prefix.is_empty(), "prefix must be non-empty");
assert!(prefix.len() < 64, "prefix is longer than 63 characters");

for b in prefix.as_bytes() {
if cfg!(feature = "delimited") && *b == b'_' {
let underscore = b'_';
let bytes = prefix.as_bytes();

assert_ne!(*bytes.first().unwrap(), underscore, "prefix cannot start with an underscore");
assert_ne!(*bytes.last().unwrap(), underscore, "prefix cannot end with an underscore");

for (index, b) in prefix.as_bytes().iter().enumerate() {
if cfg!(feature = "delimited") && *b == underscore && index > 0 {
continue;
}

Expand Down Expand Up @@ -194,7 +201,7 @@ pub fn derive_strong_id_uuid(input: proc_macro::TokenStream) -> proc_macro::Toke
quote!()
};

let uuid_v6_impl = if cfg!(all(uuid_unstable, feature = "uuid-v6")) {
let uuid_v6_impl = if cfg!(feature = "uuid-v6") {
quote! {
fn new_v6(ts: ::strong_id::uuid::Timestamp, node_id: &[u8; 6]) -> Self {
Self(::strong_id::uuid::Uuid::new_v6(ts, node_id))
Expand All @@ -208,7 +215,7 @@ pub fn derive_strong_id_uuid(input: proc_macro::TokenStream) -> proc_macro::Toke
quote!()
};

let uuid_v7_impl = if cfg!(all(uuid_unstable, feature = "uuid-v7")) {
let uuid_v7_impl = if cfg!(feature = "uuid-v7") {
quote! {
fn new_v7(ts: ::strong_id::uuid::Timestamp) -> Self {
Self(::strong_id::uuid::Uuid::new_v7(ts))
Expand All @@ -222,7 +229,7 @@ pub fn derive_strong_id_uuid(input: proc_macro::TokenStream) -> proc_macro::Toke
quote!()
};

let uuid_v8_impl = if cfg!(all(uuid_unstable, feature = "uuid-v8")) {
let uuid_v8_impl = if cfg!(feature = "uuid-v8") {
quote! {
fn new_v8(buf: [u8; 16]) -> Self {
Self(::strong_id::uuid::Uuid::new_v8(buf))
Expand Down
2 changes: 0 additions & 2 deletions tests/smoke_test/.cargo/config.toml

This file was deleted.

2 changes: 0 additions & 2 deletions tests/typeid_spec/.cargo/config.toml

This file was deleted.

6 changes: 3 additions & 3 deletions tests/typeid_spec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ edition = "2021"
publish = false

[dependencies]
libtest-mimic = "0.6"
reqwest = { version = "0.11", features = ["blocking", "json"] }
libtest-mimic = "0.7.3"
reqwest = { version = "0.12.4", features = ["blocking", "json"] }
serde = { version = "1.0", features = ["derive"] }
uuid = { version = "1.4.0", features = ["v7"] }
uuid = { version = "1.6.0", features = ["v7"] }

[dependencies.strong_id]
path = "../../strong_id"
Expand Down
15 changes: 14 additions & 1 deletion tests/typeid_spec/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ fn fetch_cases<T: Case + DeserializeOwned>() -> Vec<T> {

strong_uuid!(struct NoPrefix(Uuid));
strong_uuid!(struct Prefix(Uuid => "prefix"));
strong_uuid!(struct PrefixUnderscore(Uuid => "pre_fix"));

fn main() {
let valid_cases = fetch_cases::<ValidCase>();
Expand Down Expand Up @@ -84,7 +85,7 @@ fn main() {
.chain(valid_cases.into_iter().map(|case| {
Trial::test(format!("valid::static::{}", case.name), move || {
match case.prefix() {
Some(_prefix) => {
Some(prefix) if !prefix.contains('_') => {
let uuid = Uuid::from_str(&case.uuid).unwrap();
// encode
let encoded = Prefix::from(uuid);
Expand All @@ -96,6 +97,18 @@ fn main() {
assert_eq!(encoded.to_string(), case.typeid);
assert_eq!(*encoded.id(), uuid);
}
Some(_) => {
let uuid = Uuid::from_str(&case.uuid).unwrap();
// encode
let encoded = PrefixUnderscore::from(uuid);
assert_eq!(encoded.to_string(), case.typeid);
assert_eq!(*encoded.id(), uuid);

// decode
let encoded = PrefixUnderscore::from_str(&case.typeid).unwrap();
assert_eq!(encoded.to_string(), case.typeid);
assert_eq!(*encoded.id(), uuid);
}
None => {
let uuid = Uuid::from_str(&case.uuid).unwrap();
// encode
Expand Down

0 comments on commit 10aa504

Please sign in to comment.