Skip to content

Commit

Permalink
feat: implement UUID v6, v7 and v8 fake value generation
Browse files Browse the repository at this point in the history
Signed-off-by: Lorenzo Delgado <[email protected]>
  • Loading branch information
LNSD committed Dec 12, 2024
1 parent df5fb53 commit f0f98e8
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 16 deletions.
3 changes: 2 additions & 1 deletion fake/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rust-version = "1.63"

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
dummy = { version = "0.9", path = "../dummy_derive", optional = true }
Expand All @@ -28,7 +29,7 @@ http = { version = "1", optional = true }
semver = { version = "1", optional = true }
serde_json = { version = "1", optional = true }
ulid = { version = "1", optional = true }
uuid = { version = "1", features = ["v1", "v3", "v4", "v5"], optional = true }
uuid = { version = "1", features = ["v1", "v3", "v4", "v5", "v6", "v7", "v8"], optional = true }
time = { version = "0.3", features = ["formatting"], optional = true }
num-traits = { version = "0.2", optional = true }
rust_decimal = { version = "1", default-features = false, optional = true }
Expand Down
2 changes: 1 addition & 1 deletion fake/src/impls/bson_oid/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! bson_objectid
//! Fake _bson OID_ generation.
use bson::oid::ObjectId;

Expand Down
2 changes: 1 addition & 1 deletion fake/src/impls/ulid/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! ulid
//! Fake _ulid_ generation.
use ulid::Ulid;

Expand Down
82 changes: 76 additions & 6 deletions fake/src/impls/uuid/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
//! uuid
//! Fake _UUIDs_ generation.
//!
//! This module provides implementations for generating fake UUIDs (Universally Unique Identifiers)
//! using the [`uuid`] crate.
//!
//! please note that :
//! * all [`Dummy`] implementations for [`String`] use [to_hyphenated](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.to_hyphenated).
//! * [`Dummy<Faker>`] implementation uses [from_u128](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.from_u128)
//! Please note that:
//! * All [`Dummy`] implementations for [`String`] use [to_hyphenated](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.to_hyphenated).
//! * [`Dummy<Faker>`] implementation uses [from_u128](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.from_u128).
//!
//! # Examples
//!
//! ```rust
//! use fake::{Fake, Faker};
//! use fake::uuid::{UUIDv4, UUIDv7};
//! # use uuid::Uuid;
//!
//! // Use the `Dummy<Faker>` implementation
//! let uuid: Uuid = Faker.fake();
//!
//! // Use the `Dummy<UUIDv4>` implementation to generate a UUID instance
//! let uuid: Uuid = UUIDv4.fake();//!
//!
//! // Use the `Dummy<UUIDv7>` implementation to generate a UUID string
//! let uuid: String = UUIDv7.fake();
//! ```
use uuid::{Builder, Uuid, Variant, Version};

Expand All @@ -16,12 +36,18 @@ pub struct UUIDv3;
pub struct UUIDv4;
/// as per [new_v5](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v5)
pub struct UUIDv5;
/// as per [new_v6](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v6)
pub struct UUIDv6;
/// as per [new_v7](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v7)
pub struct UUIDv7;
/// as per [new_v8](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v8)
pub struct UUIDv8;

impl Dummy<UUIDv1> for Uuid {
fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &UUIDv1, rng: &mut R) -> Self {
let ticks = rng.gen_range(uuid::timestamp::UUID_TICKS_BETWEEN_EPOCHS..u64::MAX);
let counter = Faker.fake_with_rng(rng);
let ts = uuid::timestamp::Timestamp::from_rfc4122(ticks, counter);
let ts = uuid::timestamp::Timestamp::from_gregorian(ticks, counter);
let node_id: [u8; 6] = Faker.fake_with_rng(rng);
Uuid::new_v1(ts, &node_id)
}
Expand Down Expand Up @@ -78,8 +104,52 @@ impl Dummy<UUIDv5> for String {
}
}

impl Dummy<UUIDv6> for Uuid {
fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &UUIDv6, rng: &mut R) -> Self {
let ticks = rng.gen_range(uuid::timestamp::UUID_TICKS_BETWEEN_EPOCHS..u64::MAX);
let counter = Faker.fake_with_rng(rng);
let ts = uuid::timestamp::Timestamp::from_gregorian(ticks, counter);
let node_id: [u8; 6] = Faker.fake_with_rng(rng);
Uuid::new_v6(ts, &node_id)
}
}

impl Dummy<UUIDv6> for String {
fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UUIDv6, rng: &mut R) -> Self {
Uuid::dummy_with_rng(config, rng).hyphenated().to_string()
}
}

impl Dummy<UUIDv7> for Uuid {
fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &UUIDv7, rng: &mut R) -> Self {
let ticks = rng.gen_range(uuid::timestamp::UUID_TICKS_BETWEEN_EPOCHS..u64::MAX);
let counter = Faker.fake_with_rng(rng);
let ts = uuid::timestamp::Timestamp::from_gregorian(ticks, counter);
Uuid::new_v7(ts)
}
}

impl Dummy<UUIDv7> for String {
fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UUIDv7, rng: &mut R) -> Self {
Uuid::dummy_with_rng(config, rng).hyphenated().to_string()
}
}

impl Dummy<UUIDv8> for Uuid {
fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &UUIDv8, rng: &mut R) -> Self {
let buf: [u8; 16] = Faker.fake_with_rng(rng);
Uuid::new_v8(buf)
}
}

impl Dummy<UUIDv8> for String {
fn dummy_with_rng<R: rand::Rng + ?Sized>(config: &UUIDv8, rng: &mut R) -> Self {
Uuid::dummy_with_rng(config, rng).hyphenated().to_string()
}
}

impl Dummy<Faker> for Uuid {
fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &Faker, rng: &mut R) -> Self {
Self::from_u128(rng.gen())
Uuid::from_u128(rng.gen())
}
}
37 changes: 30 additions & 7 deletions fake/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@
//!
//! # Feature flags
//!
//! - `derive` provides `#[derive(Dummy)]`
//! - `chrono` [chrono](https://docs.rs/chrono) integration
//! - `http` [http](https://docs.rs/http) integration
//! - `ulid` [ulid](https://docs.rs/ulid) integration
//! - `uuid` [uuid](https://docs.rs/uuid) integration
//! - `derive`: Enable `#[derive(Dummy)]` macro
//! - `bigdecimal`: [bigdecimal](https://docs.rs/bigdecimal) integration
//! - `bson_oid`: [bson](https://docs.rs/bson) integration
//! - `chrono`: [chrono](https://docs.rs/chrono) integration
//! - `chrono-tz`: [chrono-tz](https://docs.rs/chrono-tz) integration
//! - `geo`: [geo-types](https://docs.rs/geo-types) integration
//! - `glam`: [glam](https://docs.rs/glam) integration
//! - `http`: [http](https://docs.rs/http) integration
//! - `rust-decimal`: [rust_decimal](https://docs.rs/rust_decimal) integration
//! - `time`: [time](https://docs.rs/time) integration
//! - `ulid`: [ulid](https://docs.rs/ulid) integration
//! - `uuid`: [uuid](https://docs.rs/uuid) integration
//!
//! # Usage
//!
Expand Down Expand Up @@ -72,7 +79,7 @@
//! println!("value from fixed seed {}", v);
//! }
//!
//! # #[cfg(feture = "always-true-rng")] {
//! # #[cfg(feature = "always-true-rng")] {
//! // Use an always true RNG so that optional types are always `Some` values. (Requires
//! // always-true-rng feature).
//! use fake::utils::AlwaysTrueRng;
Expand All @@ -81,6 +88,10 @@
//! println!("Always Some: {}", result.unwrap());
//! # }
//! ```
// Enable `doc_cfg` feature for `docs.rs`
#![cfg_attr(docsrs, feature(doc_cfg))]

#[doc(hidden)]
pub use rand;
#[doc(hidden)]
Expand Down Expand Up @@ -139,7 +150,7 @@ pub struct Faker;
///
/// # Derivable
///
/// The trait can be used with `#[derive]` if all of the type's fields
/// The trait can be used with `#[derive]` if all the type's fields
/// implement [`Fake`]. See [`Dummy`][macro@Dummy] for more.
pub trait Dummy<T>: Sized {
/// Generate a dummy value for a type.
Expand Down Expand Up @@ -218,13 +229,15 @@ pub trait Fake: Sized {
impl<T> Fake for T {}

#[cfg(feature = "geo")]
#[cfg_attr(docsrs, doc(cfg(feature = "geo")))]
fn unique<U: Dummy<Faker> + PartialEq, R: Rng + ?Sized>(rng: &mut R, len: usize) -> Vec<U> {
let mut set = Vec::<U>::new();
unique_append(&mut set, rng, len);
set
}

#[cfg(feature = "geo")]
#[cfg_attr(docsrs, doc(cfg(feature = "geo")))]
fn unique_append<U: Dummy<Faker> + PartialEq, R: Rng + ?Sized>(
set: &mut Vec<U>,
rng: &mut R,
Expand Down Expand Up @@ -252,30 +265,39 @@ pub use impls::std::result::ResultFaker;
pub use impls::std::string::StringFaker;

#[cfg(feature = "geo")]
#[cfg_attr(docsrs, doc(cfg(feature = "geo")))]
pub use impls::geo;

#[cfg(feature = "ulid")]
#[cfg_attr(docsrs, doc(cfg(feature = "ulid")))]
pub use impls::ulid;

#[cfg(feature = "uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid")))]
pub use impls::uuid;

#[cfg(feature = "rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "rust_decimal")))]
pub use impls::decimal;

#[cfg(any(feature = "bigdecimal", feature = "bigdecimal-rs"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "bigdecimal", feature = "bigdecimal-rs"))))]
pub use impls::bigdecimal;

#[cfg(feature = "serde_json")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde_json")))]
pub use impls::serde_json;

#[cfg(feature = "time")]
#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
pub use impls::time;

#[cfg(feature = "chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
pub use impls::chrono;

#[cfg(feature = "bson_oid")]
#[cfg_attr(docsrs, doc(cfg(feature = "bson_oid")))]
pub use impls::bson_oid;

/// Fake value generation for specific formats.
Expand Down Expand Up @@ -428,6 +450,7 @@ pub mod locales;
/// let b: Bar = Faker.fake();
/// ```
#[cfg(feature = "derive")]
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
pub use dummy::Dummy;

pub mod utils;

0 comments on commit f0f98e8

Please sign in to comment.