Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework optional dependencies to discourage direct use as Cargo features #589

Merged
merged 4 commits into from
Feb 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 60 additions & 39 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
14 changes: 14 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 10 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -235,6 +235,10 @@ mod v5;

#[cfg(feature = "rng")]
mod rng;
#[cfg(feature = "md5")]
mod md5;
#[cfg(feature = "sha1")]
mod sha1;

mod external;

Expand All @@ -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;

Expand Down Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}};
}

Expand Down
14 changes: 14 additions & 0 deletions src/md5.rs
Original file line number Diff line number Diff line change
@@ -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
}
8 changes: 4 additions & 4 deletions src/rng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
});
Expand All @@ -14,7 +14,7 @@ pub(crate) fn bytes() -> [u8; 16] {

#[cfg(feature = "fast-rng")]
{
rand::random()
private_rand::random()
}
}

Expand All @@ -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)
});
Expand All @@ -34,6 +34,6 @@ pub(crate) fn u16() -> u16 {

#[cfg(feature = "fast-rng")]
{
rand::random()
private_rand::random()
}
}
14 changes: 14 additions & 0 deletions src/sha1.rs
Original file line number Diff line number Diff line change
@@ -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
}
4 changes: 2 additions & 2 deletions src/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -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)
}
}

Expand Down
26 changes: 6 additions & 20 deletions src/v3.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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()
}
}

Expand All @@ -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)] = &[
(
Expand Down
26 changes: 6 additions & 20 deletions src/v5.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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()
}
}

Expand All @@ -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)] = &[
(
Expand Down