How to Generate UUID in Rust
Rust uses the uuid crate for generating RFC 4122 compliant UUIDs. This guide covers all UUID versions and common operations.
1. Setup
Add to your Cargo.toml:
[dependencies]
uuid = { version = "1.6", features = ["v4", "v7", "serde"] } 2. Generate UUID v4 (Random)
The most common UUID type, using random data.
use uuid::Uuid;
fn main() {
// Generate UUID v4
let uuid = Uuid::new_v4();
println!("{}", uuid);
// Output: "550e8400-e29b-41d4-a716-446655440000"
// Generate multiple UUIDs
for _ in 0..5 {
println!("{}", Uuid::new_v4());
}
} 3. Generate UUID v7 (Time-ordered)
UUID v7 is time-sortable and great for database primary keys.
use uuid::Uuid;
fn main() {
// Generate UUID v7 (requires "v7" feature)
let uuid = Uuid::now_v7();
println!("{}", uuid);
// Output: "018c6e9a-3b4c-7d5e-8f9a-0b1c2d3e4f5a"
// UUIDs generated close together are sortable
let uuid1 = Uuid::now_v7();
let uuid2 = Uuid::now_v7();
println!("uuid1 < uuid2: {}", uuid1 < uuid2); // Often true
} 4. UUID Validation and Parsing
use uuid::Uuid;
fn main() {
// Parse UUID from string
let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")
.expect("Invalid UUID");
println!("{}", uuid);
// Safe parsing with Result
match Uuid::parse_str("not-a-uuid") {
Ok(uuid) => println!("Valid: {}", uuid),
Err(e) => println!("Invalid: {}", e),
}
// Parse without hyphens
let uuid = Uuid::parse_str("550e8400e29b41d4a716446655440000")
.expect("Invalid UUID");
println!("{}", uuid);
// Check if nil UUID
let nil = Uuid::nil();
println!("Is nil: {}", nil.is_nil()); // true
} 5. UUID Formatting
use uuid::Uuid;
fn main() {
let uuid = Uuid::new_v4();
// Standard hyphenated format
println!("{}", uuid); // 550e8400-e29b-41d4-a716-446655440000
// Hyphenated lowercase
println!("{}", uuid.hyphenated());
// Simple (no hyphens)
println!("{}", uuid.simple()); // 550e8400e29b41d4a716446655440000
// URN format
println!("{}", uuid.urn()); // urn:uuid:550e8400-e29b-41d4-a716-446655440000
// Braced format
println!("{}", uuid.braced()); // {550e8400-e29b-41d4-a716-446655440000}
// Uppercase
let upper = uuid.hyphenated().to_string().to_uppercase();
println!("{}", upper);
} 6. UUID Properties
use uuid::Uuid;
fn main() {
let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")
.unwrap();
// Get version
println!("Version: {:?}", uuid.get_version()); // Some(Random)
// Get variant
println!("Variant: {:?}", uuid.get_variant()); // RFC4122
// Get as bytes
let bytes: &[u8; 16] = uuid.as_bytes();
println!("Bytes: {:?}", bytes);
// Create from bytes
let from_bytes = Uuid::from_bytes(*bytes);
println!("From bytes: {}", from_bytes);
} 7. Serde Serialization
use uuid::Uuid;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct User {
id: Uuid,
name: String,
}
fn main() {
let user = User {
id: Uuid::new_v4(),
name: "John".to_string(),
};
// Serialize to JSON
let json = serde_json::to_string(&user).unwrap();
println!("{}", json);
// {"id":"550e8400-e29b-41d4-a716-446655440000","name":"John"}
// Deserialize from JSON
let parsed: User = serde_json::from_str(&json).unwrap();
println!("{:?}", parsed);
} 8. Database Integration (SQLx)
use sqlx::postgres::PgPool;
use uuid::Uuid;
#[derive(sqlx::FromRow)]
struct User {
id: Uuid,
name: String,
}
async fn create_user(pool: &PgPool, name: &str) -> Result {
let id = Uuid::new_v4();
sqlx::query("INSERT INTO users (id, name) VALUES ($1, $2)")
.bind(id)
.bind(name)
.execute(pool)
.await?;
Ok(id)
}
async fn get_user(pool: &PgPool, id: Uuid) -> Result {
sqlx::query_as::<_, User>("SELECT id, name FROM users WHERE id = $1")
.bind(id)
.fetch_one(pool)
.await
} 9. UUID v1 (MAC + Time)
// Add to Cargo.toml: uuid = { version = "1.6", features = ["v1"] }
use uuid::{Uuid, timestamp::Timestamp};
fn main() {
// UUID v1 requires a node ID (usually MAC address)
let node_id = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab];
// Create timestamp context
let ts = Timestamp::now(uuid::timestamp::context::NoContext);
// Generate UUID v1
let uuid = Uuid::new_v1(ts, &node_id);
println!("{}", uuid);
} 10. Bulk Generation
use uuid::Uuid;
fn main() {
// Generate vector of UUIDs
let uuids: Vec = (0..10)
.map(|_| Uuid::new_v4())
.collect();
for uuid in &uuids {
println!("{}", uuid);
}
// Generate with iterator
let uuid_strings: Vec = (0..5)
.map(|_| Uuid::new_v4().to_string())
.collect();
println!("{:?}", uuid_strings);
} Best Practices
- Use UUID v4 for general-purpose random identifiers
- Use UUID v7 for database primary keys (time-sortable)
- Enable only the features you need in Cargo.toml
- Use
Uuid::parse_str()with proper error handling - Enable
serdefeature for JSON serialization - Store UUIDs as native UUID type in PostgreSQL for best performance
Ready to use what you learned?
Try UUID Generator now