uuid Rust Library

repository·main·Indexed 22 days ago

https://github.com/uuid-rs/uuid

A Rust implementation of the Universally Unique Identifier (UUID) standard for generating, parsing, and manipulating 128-bit unique identifiers. Version 1.24.0 provides support for multiple UUID versions (v1 through v8) via crate features, including random (v4) and sortable (v7) identifiers. It includes a Builder for custom construction, a `uuid!` macro for compile-time literals, and specialized format adapters for hyphenated, simple, URN, and braced string representations.

Tokens
6.4K
Snippets
20
Records
50
Agent score
78%

What's inside uuid

  1. Add a new fuzz test case

    main

    To add a new fuzzing target to the repository:

    1. Create a new file at fuzz/$TARGET_NAME/main.rs (e.g., fuzz/parse/main.rs). Refer to existing cases for the required structure.
    2. Register the new target by adding a [[bin]] section to fuzz/Cargo.toml.
    3. Add an entry to fuzz/canary.sh to ensure the new target is included in the canary runs.
  2. Install the `uuid` crate

    main

    To use the uuid crate in your Rust project, add it to your Cargo.toml. To enable the generation of random (v4) UUIDs, you must explicitly enable the v4 feature.

    [dependencies.uuid]
    version = "1.24.0"
    # Lets you generate random UUIDs
    features = [
        "v4",
    ]
  3. Build and run fuzz targets

    main

    After installing and configuring AFL++, you can build the fuzz targets using the fuzz/Cargo.toml manifest and the afl feature.

    To build:

    cargo afl build --manifest-path fuzz/Cargo.toml --features afl

    To run a specific fuzz target interactively (which opens the AFL TUI), use the following command, replacing $TARGET_NAME with your target name (e.g., parse):

    cargo afl fuzz -i fuzz/$TARGET_NAME/in -o fuzz/target/$TARGET_NAME fuzz/target/debug/$TARGET_NAME
    cargo afl build --manifest-path fuzz/Cargo.toml --features afl
    
    cargo afl fuzz -i fuzz/$TARGET_NAME/in -o fuzz/target/$TARGET_NAME fuzz/target/debug/$TARGET_NAME
  4. Install and configure AFL++ for fuzzing

    main

    To use the fuzz testing infrastructure, you must install cargo.afl and configure your system settings.

    1. Install cargo.afl via Cargo:
    cargo install -f argo-afl
    1. Configure your system for fuzzing:
    cargo afl config --build --force
    cargo afl system-config
  5. Format UUIDs into different string representations

    main

    The uuid crate provides several formatting types to represent a UUID in different string formats. You can access these formats using methods on a Uuid instance. Each format type implements traits that allow for encoding into a byte buffer.

    Supported formats:

    • Hyphenated: Standard 8-4-4-4-12 format (e.g., 936da01f-9abd-4d9d-80c7-02af85c822a8).
    • Simple: Hexadecimal string without hyphens (e.g., 936da01f9abd4d9d80c702af85c822a8).
    • Urn: URN format (e.g., urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8).
    • Braced: Hexadecimal string enclosed in curly braces (e.g., {936da01f-9abd-4d9d-80c7-02af85c822a8}).

    Each format can be encoded in either lowercase or uppercase.

  6. Use the Builder to construct UUIDs

    main

    The Builder type is used to construct Uuids when you need to mutate individual fields (like version or variant) during construction. Since Uuid is a Copy type, it does not provide in-place mutation methods; instead, these methods are implemented on the Builder. The Builder also provides a lower-level API that allows constructing any UUID version without requiring specific crate features or additional dependencies.

    # use uuid::{Builder, Version, Variant};
    # let rng = || [70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, 62];
    let random_bytes = rng();
    
    let uuid = Builder::from_random_bytes(random_bytes).into_uuid();
    
    assert_eq!(Some(Version::Random), uuid.get_version());
    assert_eq!(Variant::RFC4122, uuid.get_variant());
  7. Which UUID version should I use?

    main

    The choice of UUID version depends on your use case:

    • General purpose: Use Version 4 (v4) for random unique identifiers.
    • Database keys / Sortable: Use Version 7 (v7) if you need UUIDs that are sortable (e.g., for database primary keys).

    Recommendations:

    • Prefer Version 6 over Version 1.
    • Prefer Version 5 over Version 3.

    To use these, enable the corresponding feature (v1, v3, v4, v5, v6, v7, or v8) in your Cargo.toml.

  8. Format a Uuid using different string representations

    main

    The uuid crate provides several adapter structs to format a Uuid into specific string representations. You can access these via methods on the Uuid instance. These adapters implement Display, Debug, LowerHex, and UpperHex, allowing them to be used directly in format! macros or with println!.

    Available formats:

    • hyphenated(): 67e55044-10b1-426f-9247-bb680e5fe0c8
    • simple(): 67e5504410b1426f9247bb680e5fe0c8
    • urn(): urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8
    • braced(): {67e55044-10b1-426f-9247-bb680e5fe0c8}
  9. The `Timestamp` type for UUID generation

    main

    The Timestamp type abstracts the specific timestamp encoding used by different UUID versions. This allows the same type to support versions 1, 6, and 7, even though they use different epoch and precision models.

    Supported Representations

    • Versions 1 and 6: Use a bespoke timestamp consisting of 100ns ticks since the Gregorian reform (1582-10-15 00:00:00) and a 14-bit counter.
    • Version 7: Uses a standard Unix timestamp (milliseconds since 1970-01-01 00:00:00) and a larger counter.

    Key Methods

    • from_gregorian_time(ticks: u64, counter: u16): Constructs a timestamp for versions 1 and 6.
    • from_unix_time(seconds: u64, subsec_nanos: u32, counter: u128, usable_counter_bits: u8): Constructs a timestamp for version 7.
    • to_gregorian() -> (u64, u16): Returns the Gregorian ticks and 14-bit counter.
    • to_unix() -> (u64, u32): Returns the Unix seconds and sub-second nanoseconds.
  10. Format a UUID

    main

    A Uuid can be formatted in several ways using adapter methods:

    • simple(): a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8 (no hyphens).
    • hyphenated(): a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8 (default Display format).
    • urn(): urn:uuid:A1A2A3A4-B1B2-C1C2-D1D2-D3D4D5D6D7D8.
    • braced(): {a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8}.

    You can use these adapters to get a formatter that implements Display.

    # use uuid::Uuid;
    # fn main() -> Result<(), uuid::Error> {
    let my_uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?;
    
    assert_eq!(
        "urn:uuid:a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
        my_uuid.urn().to_string(),
    );
    # Ok(())
    # }
  11. Use NonNilUuid for memory-efficient optional UUIDs

    main

    The NonNilUuid type is a wrapper for UUIDs that are guaranteed not to be the nil UUID.

    It is specifically designed to make Option<NonNilUuid> as memory-efficient as a standard Uuid. While a standard Option<Uuid> typically increases the memory footprint due to alignment/padding, Option<NonNilUuid> takes up the same space as a single Uuid because the nil value is used to represent None internally.

    /// This is useful for representing optional UUIDs more efficiently, as `Option<NonNilUuid>`
    /// takes up the same space as `Uuid`.
  12. Reproduce fuzzing crashes

    main

    Crashes discovered during fuzzing are saved in the target directory. To re-test these crashes and verify them using the regular unit test suite, run the tests specifically for the fuzz manifest:

    cargo test --manifest-path fuzz/Cargo.toml