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

feat: implement UUID v6, v7 and v8 fake value generation #207

Merged
merged 1 commit into from
Dec 15, 2024
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
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
90 changes: 80 additions & 10 deletions fake/src/impls/uuid/mod.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,53 @@
//! uuid
//! Fake _UUIDs_ generation.
//!
//! 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)
//! 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).
//!
//! # 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};

use crate::{Dummy, Fake, Faker};

/// as per [new_v1](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v1)
/// As per [new_v1](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v1)
pub struct UUIDv1;
/// as per [new_v3](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v3)
/// As per [new_v3](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v3)
pub struct UUIDv3;
/// as per [new_v4](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v4)
/// As per [new_v4](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v4)
pub struct UUIDv4;
/// as per [new_v5](https://docs.rs/uuid/latest/uuid/struct.Uuid.html#method.new_v5)
/// 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())
}
}
42 changes: 34 additions & 8 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 All @@ -32,7 +39,7 @@
//! println!("tuple {:?}", tuple);
//! println!("String {:?}", Faker.fake::<String>());
//!
//! // types U can used to generate fake value T, if `T: Dummy<U>`
//! // types U can `be used to generate fake value T, if `T: Dummy<U>`
//! println!("String {:?}", (8..20).fake::<String>());
//! println!("u32 {:?}", (8..20).fake::<u32>());
//!
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,42 @@ 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 +453,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;
Loading