UUIDs (Universally Unique Identifiers) são identificadores de 128 bits usados para identificar recursos de forma única sem coordenação central. São essenciais em sistemas distribuídos, bancos de dados, APIs e mensageria. A crate uuid do Rust suporta todas as versões do padrão, incluindo o moderno UUIDv7 ordenável por tempo.
Dependências
[package]
name = "receita-uuid"
version = "0.1.0"
edition = "2021"
[dependencies]
uuid = { version = "1", features = ["v4", "v7"] }
Código Completo
use uuid::Uuid;
fn main() {
// =============================================
// 1. Gerar UUID v4 (aleatório)
// =============================================
println!("=== UUID v4 (aleatório) ===");
let id = Uuid::new_v4();
println!("UUID v4: {}", id);
println!("Bytes: {:?}", id.as_bytes());
println!("Versão: {}", id.get_version_num());
// Gerar vários UUIDs
println!("\nVários UUIDs v4:");
for i in 1..=5 {
println!(" {}: {}", i, Uuid::new_v4());
}
// =============================================
// 2. Gerar UUID v7 (ordenável por tempo)
// =============================================
println!("\n=== UUID v7 (ordenável por tempo) ===");
let id1 = Uuid::now_v7();
let id2 = Uuid::now_v7();
let id3 = Uuid::now_v7();
println!("UUID v7 #1: {}", id1);
println!("UUID v7 #2: {}", id2);
println!("UUID v7 #3: {}", id3);
println!("Ordenados? {} < {} < {}", id1 < id2, id2 < id3, id1 < id3);
println!("(UUIDs v7 são ordenáveis por tempo de criação)");
// =============================================
// 3. Parse de string para UUID
// =============================================
println!("\n=== Parse de String ===");
// Formato padrão com hifens
let id = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
println!("Parsed: {}", id);
// Formato sem hifens
let id = Uuid::parse_str("550e8400e29b41d4a716446655440000").unwrap();
println!("Sem hifens: {}", id);
// Formato com chaves (URN)
let id = Uuid::parse_str("{550e8400-e29b-41d4-a716-446655440000}").unwrap();
println!("Com chaves: {}", id);
// Tratando erro de parse
match Uuid::parse_str("não-é-uuid") {
Ok(id) => println!("Parsed: {}", id),
Err(e) => println!("Erro de parse: {}", e),
}
// =============================================
// 4. Formatos de exibição
// =============================================
println!("\n=== Formatos de Exibição ===");
let id = Uuid::new_v4();
println!("Display (padrão): {}", id);
println!("Hyphenated: {}", id.hyphenated());
println!("Simple (sem -): {}", id.simple());
println!("URN: {}", id.urn());
println!("Braced: {}", id.braced());
// =============================================
// 5. UUID nil e max
// =============================================
println!("\n=== Valores Especiais ===");
let nil = Uuid::nil();
let max = Uuid::max();
println!("Nil UUID: {}", nil);
println!("Max UUID: {}", max);
println!("Nil é nil? {}", nil.is_nil());
println!("Max é max? {}", max.is_max());
// =============================================
// 6. Comparação e ordenação
// =============================================
println!("\n=== Comparação e Ordenação ===");
let mut ids: Vec<Uuid> = (0..5).map(|_| Uuid::new_v4()).collect();
println!("Desordenados:");
for id in &ids {
println!(" {}", id);
}
ids.sort();
println!("Ordenados:");
for id in &ids {
println!(" {}", id);
}
// Comparação
let a = Uuid::new_v4();
let b = Uuid::new_v4();
println!("\na == b? {}", a == b);
println!("a != b? {}", a != b);
// =============================================
// 7. UUID como chave de HashMap
// =============================================
println!("\n=== UUID como Chave de HashMap ===");
use std::collections::HashMap;
#[derive(Debug)]
struct Usuario {
id: Uuid,
nome: String,
}
let mut usuarios: HashMap<Uuid, Usuario> = HashMap::new();
let id1 = Uuid::new_v4();
let id2 = Uuid::new_v4();
usuarios.insert(id1, Usuario { id: id1, nome: "Ana".into() });
usuarios.insert(id2, Usuario { id: id2, nome: "Bia".into() });
// Buscar por UUID
if let Some(u) = usuarios.get(&id1) {
println!("Encontrado: {} ({})", u.nome, u.id);
}
println!("Total de usuários: {}", usuarios.len());
// =============================================
// 8. Exemplo prático: gerador de IDs
// =============================================
println!("\n=== Gerador de IDs ===");
struct IdGenerator {
prefixo: String,
}
impl IdGenerator {
fn new(prefixo: &str) -> Self {
IdGenerator { prefixo: prefixo.to_string() }
}
fn proximo(&self) -> String {
format!("{}_{}", self.prefixo, Uuid::new_v4().simple())
}
fn proximo_curto(&self) -> String {
let uuid = Uuid::new_v4();
let curto = &uuid.simple().to_string()[..8];
format!("{}_{}", self.prefixo, curto)
}
}
let gen_pedido = IdGenerator::new("PED");
let gen_nota = IdGenerator::new("NF");
println!("Pedido: {}", gen_pedido.proximo());
println!("Pedido: {}", gen_pedido.proximo());
println!("Nota: {}", gen_nota.proximo());
println!("Curto: {}", gen_pedido.proximo_curto());
println!("Curto: {}", gen_pedido.proximo_curto());
}
Saída do Programa
=== UUID v4 (aleatório) ===
UUID v4: 3f7e9a12-4b5c-4d6e-8f1a-2b3c4d5e6f7a
Bytes: [63, 126, 154, 18, 75, 92, 77, 110, 143, 26, 43, 60, 77, 94, 111, 122]
Versão: 4
Vários UUIDs v4:
1: a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5
2: 11223344-5566-4778-899a-bbccddeeff00
...
=== UUID v7 (ordenável por tempo) ===
UUID v7 #1: 01953e8a-1234-7abc-8def-0123456789ab
UUID v7 #2: 01953e8a-1235-7bcd-8ef0-123456789abc
UUID v7 #3: 01953e8a-1236-7cde-8f01-23456789abcd
Ordenados? true < true < true
(UUIDs v7 são ordenáveis por tempo de criação)
=== Parse de String ===
Parsed: 550e8400-e29b-41d4-a716-446655440000
Sem hifens: 550e8400-e29b-41d4-a716-446655440000
Com chaves: 550e8400-e29b-41d4-a716-446655440000
Erro de parse: invalid character: expected an optional prefix ...
=== Formatos de Exibição ===
Display (padrão): 3f7e9a12-4b5c-4d6e-8f1a-2b3c4d5e6f7a
Hyphenated: 3f7e9a12-4b5c-4d6e-8f1a-2b3c4d5e6f7a
Simple (sem -): 3f7e9a124b5c4d6e8f1a2b3c4d5e6f7a
URN: urn:uuid:3f7e9a12-4b5c-4d6e-8f1a-2b3c4d5e6f7a
Braced: {3f7e9a12-4b5c-4d6e-8f1a-2b3c4d5e6f7a}
=== Valores Especiais ===
Nil UUID: 00000000-0000-0000-0000-000000000000
Max UUID: ffffffff-ffff-ffff-ffff-ffffffffffff
Nil é nil? true
Max é max? true
=== Gerador de IDs ===
Pedido: PED_3f7e9a124b5c4d6e8f1a2b3c4d5e6f7a
Pedido: PED_a1b2c3d4e5f64a7b8c9de0f1a2b3c4d5
Nota: NF_11223344556647788899bbccddeeff00
Curto: PED_3f7e9a12
Curto: PED_a1b2c3d4
UUID v4 vs v7
| Versão | Baseado em | Ordenável | Uso ideal |
|---|---|---|---|
| v4 | Aleatório | Nao | IDs genéricos, tokens |
| v7 | Timestamp + aleatório | Sim | Chaves primárias de banco, logs |
UUIDv7 e recomendado para chaves primárias de banco de dados porque a ordenação por tempo melhora a performance de insercao em indices B-tree. Se nao precisa de ordenacao temporal, use UUIDv4.
Veja Também
- Gerar Hash SHA-256 em Rust — outra forma de gerar identificadores derivados de dados
- Usar HashMap em Rust — use UUIDs como chaves de HashMap
- Tutorial: API REST com Axum — UUIDs como identificadores de recursos REST
- Tutorial: Rust e PostgreSQL — armazene UUIDs no banco de dados
- Rust Cheatsheet — referência rápida de tipos e crates
- Geração de UUID em Go — compare com o pacote uuid de Go