diff --git a/Cargo.toml b/Cargo.toml index ceabe259..89f69179 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,75 +53,96 @@ repository = "uuid-rs/uuid" [features] default = ["std"] std = [] -macro-diagnostics = ["uuid-macro-internal"] +macro-diagnostics = ["private_uuid-macro-internal"] -v1 = ["atomic"] -v3 = ["md-5"] +v1 = ["private_atomic"] +v3 = ["md5"] v4 = ["rng"] -v5 = ["sha-1"] +v5 = ["sha1"] -js = ["getrandom", "getrandom/js"] +js = ["private_getrandom", "private_getrandom/js"] -rng = ["getrandom"] -fast-rng = ["rng", "rand"] +rng = ["private_getrandom"] +fast-rng = ["rng", "private_rand"] -# Unstable features (these also need RUSTFLAGS="--cfg uuid_unstable" to work) -zerocopy-unstable = ["zerocopy"] +sha1 = ["private_sha1"] +md5 = ["private_md-5"] -# Private -[dependencies.getrandom] +# Public: Used in trait impls on `Uuid` +[dependencies.serde] +default-features = false optional = true -version = "0.2" +version = "1.0.56" + +# Public: Used in trait impls on `Uuid` +[dependencies.slog] +optional = true +version = "2" + +# Public: Used in trait impls on `Uuid` +[dependencies.arbitrary] +optional = true +version = "1" + +# Public (unstable): Used in `zerocopy` derive +# Unstable: also need RUSTFLAGS="--cfg uuid_unstable" to work +# This feature may break between releases, or be removed entirely before +# stabilization. +# See: https://github.com/uuid-rs/uuid/issues/588 +[dependencies.zerocopy] +optional = true +version = "0.6" # Private -[dependencies.rand] +# Don't depend on this optional feature directly: it may change at any time +# use the `rng` feature instead +[dependencies.private_getrandom] +package = "getrandom" optional = true -version = "0.8" +version = "0.2" # Private -[dependencies.atomic] -default-features = false +# Don't depend on this optional feature directly: it may change at any time +# use the `fast-rng` feature instead +[dependencies.private_rand] +package = "rand" optional = true -version = "0.5" +version = "0.8" # Private -[dependencies.md-5] +# Don't depend on this optional feature directly: it may change at any time +# Use the `md5` feature instead +[dependencies.private_md-5] +package = "md-5" default-features = false optional = true version = "0.10" # Private -[dependencies.sha-1] +# Don't depend on this optional feature directly: it may change at any time +# Use the `sha1` feature instead +[dependencies.private_sha1] +package = "sha1" default-features = false optional = true -version = "0.9" +version = "0.10" # Public: Re-exported -[dependencies.uuid-macro-internal] +# Don't depend on this optional feature directly: it may change at any time +# Use the `macro-diagnostics` feature instead +[dependencies.private_uuid-macro-internal] +package = "uuid-macro-internal" version = "1.0.0-alpha.1" path = "macros" optional = true -# Public: Used in trait impls on `Uuid` -[dependencies.serde] +# Private +# Don't depend on this optional feature directly: it may change at any time +[dependencies.private_atomic] +package = "atomic" default-features = false optional = true -version = "1.0.56" - -# Public: Used in trait impls on `Uuid` -[dependencies.slog] -optional = true -version = "2" - -# Public: Used in trait impls on `Uuid` -[dependencies.arbitrary] -optional = true -version = "1" - -# Public (unstable): Used in `zerocopy` derive -[dependencies.zerocopy] -optional = true -version = "0.6" +version = "0.5" [dev-dependencies.bincode] version = "1.0" diff --git a/src/builder.rs b/src/builder.rs index 3bff95b6..185abf13 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -544,6 +544,20 @@ impl Builder { .with_version(Version::Random) } + /// Creates a `Builder` using the supplied MD5 hashed bytes. + pub const fn from_md5_bytes(b: Bytes) -> Self { + Builder(Uuid::from_bytes(b)) + .with_variant(Variant::RFC4122) + .with_version(Version::Md5) + } + + /// Creates a `Builder` using the supplied SHA1 hashed bytes. + pub const fn from_sha1_bytes(b: Bytes) -> Self { + Builder(Uuid::from_bytes(b)) + .with_variant(Variant::RFC4122) + .with_version(Version::Sha1) + } + /// Creates a `Builder` using the supplied bytes. /// /// # Errors diff --git a/src/lib.rs b/src/lib.rs index c9bb731e..e361612b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,7 +97,7 @@ //! Some features are unstable. They may be incomplete or depend on other //! unstable libraries. These include: //! -//! * `zerocopy-unstable` - adds support for zero-copy deserialization using the +//! * `zerocopy` - adds support for zero-copy deserialization using the //! `zerocopy` library. //! //! Unstable features may break between minor releases. @@ -212,10 +212,10 @@ extern crate std; extern crate core as std; // Check that unstable features are accompanied by a the `uuid_unstable` cfg -#[cfg(all(not(uuid_unstable), feature = "zerocopy-unstable"))] -compile_error!("The `zerocopy-unstable` feature is unstable and may break between releases. Please also pass `RUSTFLAGS=\"--cfg uuid_unstable\"` to allow it."); +#[cfg(all(not(uuid_unstable), feature = "zerocopy"))] +compile_error!("The `zerocopy` feature is unstable and may break between releases. Please also pass `RUSTFLAGS=\"--cfg uuid_unstable\"` to allow it."); -#[cfg(feature = "zerocopy-unstable")] +#[cfg(feature = "zerocopy")] use zerocopy::{AsBytes, FromBytes, Unaligned}; mod builder; @@ -235,6 +235,10 @@ mod v5; #[cfg(feature = "rng")] mod rng; +#[cfg(feature = "md5")] +mod md5; +#[cfg(feature = "sha1")] +mod sha1; mod external; @@ -243,7 +247,7 @@ mod macros; #[doc(hidden)] #[cfg(feature = "macro-diagnostics")] -pub extern crate uuid_macro_internal; +pub extern crate private_uuid_macro_internal; use crate::std::convert; @@ -392,7 +396,7 @@ pub enum Variant { /// The `Uuid` type is always guaranteed to be have the same ABI as [`Bytes`]. #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr( - feature = "zerocopy-unstable", + feature = "zerocopy", derive(AsBytes, FromBytes, Unaligned) )] #[repr(transparent)] diff --git a/src/macros.rs b/src/macros.rs index de200486..7136718a 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -5,7 +5,7 @@ macro_rules! define_uuid_macro { #[macro_export] macro_rules! uuid { ($uuid:literal) => {{ - $crate::Uuid::from_bytes($crate::uuid_macro_internal::parse_lit!($uuid)) + $crate::Uuid::from_bytes($crate::private_uuid_macro_internal::parse_lit!($uuid)) }}; } diff --git a/src/md5.rs b/src/md5.rs new file mode 100644 index 00000000..3eb21fe8 --- /dev/null +++ b/src/md5.rs @@ -0,0 +1,14 @@ +#[cfg(feature = "v3")] +pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] { + use private_md_5::{Md5, Digest}; + + let mut hasher = Md5::new(); + + hasher.update(ns); + hasher.update(src); + + let mut bytes = [0; 16]; + bytes.copy_from_slice(&hasher.finalize()[..16]); + + bytes +} diff --git a/src/rng.rs b/src/rng.rs index 17859db8..fa21b626 100644 --- a/src/rng.rs +++ b/src/rng.rs @@ -4,7 +4,7 @@ pub(crate) fn bytes() -> [u8; 16] { { let mut bytes = [0u8; 16]; - getrandom::getrandom(&mut bytes).unwrap_or_else(|err| { + private_getrandom::getrandom(&mut bytes).unwrap_or_else(|err| { // NB: getrandom::Error has no source; this is adequate display panic!("could not retrieve random bytes for uuid: {}", err) }); @@ -14,7 +14,7 @@ pub(crate) fn bytes() -> [u8; 16] { #[cfg(feature = "fast-rng")] { - rand::random() + private_rand::random() } } @@ -24,7 +24,7 @@ pub(crate) fn u16() -> u16 { { let mut bytes = [0u8; 2]; - getrandom::getrandom(&mut bytes).unwrap_or_else(|err| { + private_getrandom::getrandom(&mut bytes).unwrap_or_else(|err| { // NB: getrandom::Error has no source; this is adequate display panic!("could not retrieve random bytes for uuid: {}", err) }); @@ -34,6 +34,6 @@ pub(crate) fn u16() -> u16 { #[cfg(feature = "fast-rng")] { - rand::random() + private_rand::random() } } diff --git a/src/sha1.rs b/src/sha1.rs new file mode 100644 index 00000000..da0e00e3 --- /dev/null +++ b/src/sha1.rs @@ -0,0 +1,14 @@ +#[cfg(feature = "v5")] +pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] { + use private_sha1::{Sha1, Digest}; + + let mut hasher = Sha1::new(); + + hasher.update(ns); + hasher.update(src); + + let mut bytes = [0; 16]; + bytes.copy_from_slice(&hasher.finalize()[..16]); + + bytes +} diff --git a/src/v1.rs b/src/v1.rs index 86716baf..c8b425e0 100644 --- a/src/v1.rs +++ b/src/v1.rs @@ -5,7 +5,7 @@ use crate::{Uuid, Version}; -use atomic::Atomic; +use private_atomic::{Atomic, Ordering}; /// The number of 100 ns ticks between the UUID epoch /// `1582-10-15 00:00:00` and the Unix epoch `1970-01-01 00:00:00`. @@ -295,7 +295,7 @@ impl ClockSequence for Context { // increment the clock sequence we want to wrap once it becomes larger // than what we can represent in a "u14". Otherwise there'd be patches // where the clock sequence doesn't change regardless of the timestamp - self.count.fetch_add(1, atomic::Ordering::AcqRel) % (u16::MAX >> 2) + self.count.fetch_add(1, Ordering::AcqRel) % (u16::MAX >> 2) } } diff --git a/src/v3.rs b/src/v3.rs index 2fa06114..d529f3ee 100644 --- a/src/v3.rs +++ b/src/v3.rs @@ -1,6 +1,4 @@ -use crate::{Uuid, Variant, Version}; - -use md5::{Digest, Md5}; +use crate::Uuid; impl Uuid { /// Creates a UUID using a name from a namespace, based on the MD5 @@ -32,22 +30,7 @@ impl Uuid { /// [`NAMESPACE_URL`]: #associatedconstant.NAMESPACE_URL /// [`NAMESPACE_X500`]: #associatedconstant.NAMESPACE_X500 pub fn new_v3(namespace: &Uuid, name: &[u8]) -> Uuid { - let mut hasher = Md5::new(); - - hasher.update(namespace.as_bytes()); - hasher.update(name); - - let buffer = hasher.finalize(); - - let mut bytes = crate::Bytes::default(); - bytes.copy_from_slice(&buffer[..16]); - - let mut builder = crate::Builder::from_bytes(bytes); - builder - .set_variant(Variant::RFC4122) - .set_version(Version::Md5); - - builder.into_uuid() + crate::Builder::from_md5_bytes(crate::md5::hash(namespace.as_bytes(), name)).into_uuid() } } @@ -58,7 +41,10 @@ mod tests { #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; - use crate::std::string::ToString; + use crate::{ + Variant, Version, + std::string::ToString, + }; static FIXTURE: &'static [(&'static Uuid, &'static str, &'static str)] = &[ ( diff --git a/src/v5.rs b/src/v5.rs index 7e4ab326..f8396423 100644 --- a/src/v5.rs +++ b/src/v5.rs @@ -1,6 +1,4 @@ -use crate::{Uuid, Variant, Version}; - -use sha1::{Digest, Sha1}; +use crate::Uuid; impl Uuid { /// Creates a UUID using a name from a namespace, based on the SHA-1 hash. @@ -31,22 +29,7 @@ impl Uuid { /// [`NAMESPACE_URL`]: struct.Uuid.html#associatedconst.NAMESPACE_URL /// [`NAMESPACE_X500`]: struct.Uuid.html#associatedconst.NAMESPACE_X500 pub fn new_v5(namespace: &Uuid, name: &[u8]) -> Uuid { - let mut hasher = Sha1::new(); - - hasher.update(namespace.as_bytes()); - hasher.update(name); - - let buffer = hasher.finalize(); - - let mut bytes = crate::Bytes::default(); - bytes.copy_from_slice(&buffer[..16]); - - let mut builder = crate::Builder::from_bytes(bytes); - builder - .set_variant(Variant::RFC4122) - .set_version(Version::Sha1); - - builder.into_uuid() + crate::Builder::from_sha1_bytes(crate::sha1::hash(namespace.as_bytes(), name)).into_uuid() } } @@ -57,7 +40,10 @@ mod tests { #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; - use crate::std::string::ToString; + use crate::{ + Variant, Version, + std::string::ToString, + }; static FIXTURE: &'static [(&'static Uuid, &'static str, &'static str)] = &[ (