Install uuid Crate with Cargo
The uuid crate is the standard UUID implementation for Rust, providing type-safe UUID generation with feature flags for different UUID versions and optional dependencies. Add it to your Cargo.toml with the specific UUID version features you need.
Cargo.toml Configuration
[dependencies]
uuid = { version = "1.7", features = ["v4", "v7"] }
# With serde support for serialization
uuid = { version = "1.7", features = ["v4", "serde"] }
Generate UUIDs with Different Versions
Rust's uuid crate supports all UUID versions through feature flags. Choose UUID v4 for random generation, v7 for timestamp-based sortable UUIDs, or v1 for backward compatibility. Each version requires enabling its corresponding feature in Cargo.toml.
use uuid::Uuid;
fn main() {
// UUID v4 - Random (requires "v4" feature)
let id = Uuid::new_v4();
println!("{}", id);
// Output: 550e8400-e29b-41d4-a716-446655440000
// UUID v7 - Timestamp-based, sortable (requires "v7" feature)
let id_v7 = Uuid::now_v7();
println!("{}", id_v7);
// Convert to string
let uuid_string = id.to_string();
// Different string formats
let hyphenated = id.hyphenated().to_string();
let simple = id.simple().to_string(); // No hyphens
let urn = id.urn().to_string(); // URN format
}
Parse and Validate UUID Strings
Rust's strong type system ensures UUID validation at compile time when possible. Use parse_str for runtime validation with Result types, providing safe error handling for invalid UUID strings from user input or external sources.
Parse with Error Handling
use uuid::Uuid;
// Parse from string
let uuid_str = "550e8400-e29b-41d4-a716-446655440000";
let uuid = Uuid::parse_str(uuid_str).unwrap();
// Safe parsing with match
match Uuid::parse_str(uuid_str) {
Ok(id) => println!("Valid: {}", id),
Err(e) => println!("Invalid UUID: {}", e),
}
Nil UUID Check
use uuid::Uuid;
// Nil UUID (all zeros)
let nil = Uuid::nil();
// Check if UUID is nil
if id.is_nil() {
println!("UUID is nil");
}
// Get version
println!("Version: {:?}", id.get_version());
Serde Integration for JSON Serialization
Enable the "serde" feature to automatically serialize and deserialize UUIDs in JSON, MessagePack, or any serde-compatible format. This is essential for REST APIs, database storage, and configuration files.
use uuid::Uuid;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct User {
id: Uuid,
name: String,
email: String,
}
fn main() {
let user = User {
id: Uuid::new_v4(),
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
};
// Serialize to JSON
let json = serde_json::to_string(&user).unwrap();
println!("{}", json);
// {"id":"550e8400-e29b-41d4-a716-446655440000","name":"Alice","email":"alice@example.com"}
// Deserialize from JSON
let deserialized: User = serde_json::from_str(&json).unwrap();
println!("{:?}", deserialized);
}
Feature Flags for UUID Versions
The uuid crate uses feature flags to enable specific UUID versions, keeping your binary size small by only including the code you need. Enable multiple versions by listing them in the features array.
| Feature | UUID Version | Description |
|---|---|---|
| v1 | Version 1 | Timestamp + MAC address |
| v3 | Version 3 | MD5 hash namespace |
| v4 | Version 4 | Random (most common) |
| v5 | Version 5 | SHA-1 hash namespace |
| v6 | Version 6 | Reordered timestamp |
| v7 | Version 7 | Unix timestamp (sortable) |
| serde | - | Serialization support |
Database Integration with Diesel ORM
Use UUIDs as primary keys in Diesel ORM for PostgreSQL, MySQL, and SQLite. The uuid crate integrates seamlessly with Diesel's type system, providing compile-time guarantees for database operations.
use diesel::prelude::*;
use uuid::Uuid;
#[derive(Queryable, Insertable)]
#[diesel(table_name = users)]
pub struct User {
pub id: Uuid,
pub name: String,
pub email: String,
}
// Create new user with UUID
pub fn create_user(conn: &mut PgConnection, name: &str, email: &str) -> User {
use crate::schema::users;
let new_user = User {
id: Uuid::new_v4(),
name: name.to_string(),
email: email.to_string(),
};
diesel::insert_into(users::table)
.values(&new_user)
.execute(conn)
.expect("Error saving new user");
new_user
}