Loading page…
Rust walkthroughs
Loading page…
uuid::Uuid::parse_str validate UUID format and what error information does it provide?uuid::Uuid::parse_str validates that a string conforms to the UUID format specification, accepting both hyphenated (canonical) and non-hyphenated (simple) representations. The function returns Result<Uuid, Error> where the error type provides detailed information about why parsing failed. Validation checks include: correct length (32 hex digits for simple format, 36 characters for hyphenated), valid hexadecimal characters, proper hyphen placement at positions 8, 13, 18, and 23, and optionally valid UUID version and variant fields. The error type distinguishes between different failure modes, returning specific error variants for invalid length, invalid characters, and incorrect group positions.
use uuid::Uuid;
fn main() -> Result<(), uuid::Error> {
// Parse a hyphenated UUID
let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?;
println!("Parsed: {}", uuid);
// Parse a simple UUID (no hyphens)
let uuid_simple = Uuid::parse_str("550e8400e29b41d4a716446655440000")?;
println!("Parsed simple: {}", uuid_simple);
Ok(())
}parse_str accepts both hyphenated and simple UUID formats.
use uuid::Uuid;
fn main() {
// Hyphenated (canonical) format: 8-4-4-4-12 hex digits
let hyphenated = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000");
assert!(hyphenated.is_ok());
// Simple format: 32 hex digits without hyphens
let simple = Uuid::parse_str("550e8400e29b41d4a716446655440000");
assert!(simple.is_ok());
// Uppercase is valid
let upper = Uuid::parse_str("550E8400-E29B-41D4-A716-446655440000");
assert!(upper.is_ok());
// Mixed case is valid
let mixed = Uuid::parse_str("550e8400-E29b-41D4-a716-446655440000");
assert!(mixed.is_ok());
// Braced format is also accepted (curly braces are stripped)
let braced = Uuid::parse_str("{550e8400-e29b-41d4-a716-446655440000}");
assert!(braced.is_ok());
// URN format is also accepted
let urn = Uuid::parse_str("urn:uuid:550e8400-e29b-41d4-a716-446655440000");
assert!(urn.is_ok());
}Multiple formats are accepted: hyphenated, simple, braced, and URN.
use uuid::Uuid;
fn main() {
let result = Uuid::parse_str("invalid");
match result {
Ok(uuid) => println!("UUID: {}", uuid),
Err(e) => {
// uuid::Error provides error information
println!("Error kind: {:?}", e);
println!("Error message: {}", e);
}
}
}The error type is uuid::Error, which implements std::fmt::Display and std::fmt::Debug.
use uuid::Uuid;
fn main() {
// Too short
let too_short = Uuid::parse_str("550e8400-e29b-41d4-a716");
println!("Too short: {:?}", too_short);
// Err(InvalidLength(20, Expected(32, 36)))
// Too long
let too_long = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000-extra");
println!("Too long: {:?}", too_long);
// Err(InvalidLength(42, Expected(32, 36)))
}InvalidLength error reports the actual length and expected lengths.
use uuid::Uuid;
fn main() {
// Non-hexadecimal character
let invalid_char = Uuid::parse_str("550e8400-g29b-41d4-a716-446655440000");
println!("Invalid char: {:?}", invalid_char);
// 'g' is not a valid hex character
// Invalid character at specific position
let with_space = Uuid::parse_str("550e8400-e29b-41d4-a716-44665544 000");
println!("With space: {:?}", with_space);
// Space is invalid
}InvalidCharacter error reports the position and invalid character.
use uuid::Uuid;
fn main() {
// Hyphen in wrong position
let wrong_hyphen = Uuid::parse_str("550e8400e-29b-41d4-a716-446655440000");
println!("Wrong hyphen: {:?}", wrong_hyphen);
// Hyphen at position 9 instead of 8
// Missing hyphen where expected
let missing_hyphen = Uuid::parse_str("550e8400e29b-41d4a716446655440000");
println!("Missing hyphen: {:?}", missing_hyphen);
// Hyphens must be at positions 8, 13, 18, 23
}InvalidGroup error reports misplaced hyphens.
use uuid::Uuid;
fn main() {
// The error provides context about what went wrong
// InvalidLength(found, expected)
let err1 = Uuid::parse_str("short").unwrap_err();
println!("Length error: {}", err1);
// InvalidCharacter(found, position)
let err2 = Uuid::parse_str("550e8400-g29b-41d4-a716-446655440000").unwrap_err();
println!("Character error: {}", err2);
// InvalidGroup(found, expected, position) - for hyphen errors
let err3 = Uuid::parse_str("550e8400e-29b-41d4-a716-446655440000").unwrap_err();
println!("Group error: {}", err3);
}Error variants provide specific information about the failure.
use uuid::Uuid;
fn main() -> Result<(), uuid::Error> {
// From &str
let from_str = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?;
// From String (String derefs to &str)
let from_string = Uuid::parse_str(&String::from("550e8400-e29b-41d4-a716-446655440000"))?;
// From bytes (without parsing)
let bytes = [
0x55, 0x0e, 0x84, 0x00, 0xe2, 0x9b, 0x41, 0xd4,
0xa7, 0x16, 0x44, 0x66, 0x55, 0x44, 0x00, 0x00,
];
let from_bytes = Uuid::from_bytes(bytes);
// from_bytes doesn't parse - it directly constructs
Ok(())
}parse_str handles string input; from_bytes creates directly from bytes.
use uuid::Uuid;
use std::str::FromStr;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Using FromStr trait
let uuid1 = "550e8400-e29b-41d4-a716-446655440000".parse::<Uuid>()?;
// Using TryFrom
let uuid2 = Uuid::try_from("550e8400-e29b-41d4-a716-446655440000")?;
// Both use the same parsing logic as parse_str
assert_eq!(uuid1, uuid2);
Ok(())
}Uuid implements FromStr and TryFrom<&str>, delegating to parse_str.
use uuid::Uuid;
fn main() {
// Hyphenated: 36 characters (32 hex + 4 hyphens)
// Groups: 8-4-4-4-12
let hyphenated = "550e8400-e29b-41d4-a716-446655440000";
// Simple: 32 characters (all hex digits)
let simple = "550e8400e29b41d4a716446655440000";
// Both parse to the same UUID
let h = Uuid::parse_str(hyphenated).unwrap();
let s = Uuid::parse_str(simple).unwrap();
assert_eq!(h, s);
assert_eq!(h.hyphenated().to_string(), hyphenated);
}Hyphenated and simple formats represent the same UUID.
use uuid::Uuid;
fn main() {
// Braced format: {uuid}
let braced = Uuid::parse_str("{550e8400-e29b-41d4-a716-446655440000}");
assert!(braced.is_ok());
// URN format: urn:uuid:uuid
let urn = Uuid::parse_str("urn:uuid:550e8400-e29b-41d4-a716-446655440000");
assert!(urn.is_ok());
// These are convenience formats that get normalized
let uuid = braced.unwrap();
println!("Hyphenated: {}", uuid.hyphenated());
}Braced and URN formats are accepted and normalized.
use uuid::Uuid;
fn main() {
// All hex characters are case-insensitive
let lowercase = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
let uppercase = Uuid::parse_str("550E8400-E29B-41D4-A716-446655440000").unwrap();
let mixed = Uuid::parse_str("550e8400-E29b-41D4-A716-446655440000").unwrap();
// All produce the same UUID
assert_eq!(lowercase, uppercase);
assert_eq!(lowercase, mixed);
// Display outputs lowercase by default
println!("{}", lowercase); // 550e8400-e29b-41d4-a716-446655440000
}Hex characters are case-insensitive; display is lowercase.
use uuid::Uuid;
fn main() {
// Valid: 0-9, a-f, A-F
// These are all valid
assert!(Uuid::parse_str("00000000-0000-0000-0000-000000000000").is_ok());
assert!(Uuid::parse_str("ffffffff-ffff-ffff-ffff-ffffffffffff").is_ok());
assert!(Uuid::parse_str("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF").is_ok());
assert!(Uuid::parse_str("ABCDEF12-1234-5678-9ABC-DEF012345678").is_ok());
// These are invalid (not hex characters)
assert!(Uuid::parse_str("gggggggg-gggg-gggg-gggg-gggggggggggg").is_err());
assert!(Uuid::parse_str("550e8400-z29b-41d4-a716-446655440000").is_err());
}Only hexadecimal characters (0-9, a-f, A-F) are valid in UUID positions.
use uuid::Uuid;
fn main() {
// Version is in the "4" position (6th octet, high nibble)
// Format: xxxxxxxx-xxxx-Vxxx-xxxx-xxxxxxxxxxxx
// V should be 1-5 for standard versions
// Version 1 (time-based)
let v1 = Uuid::parse_str("550e8400-e29b-11d4-a716-446655440000").unwrap();
println!("Version: {}", v1.get_version().unwrap());
// Version 4 (random)
let v4 = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
println!("Version: {}", v4.get_version().unwrap());
// Version field is parsed but not validated by parse_str
// Any value 0-15 is accepted
}parse_str accepts any version number; version is parsed, not enforced.
use uuid::Uuid;
fn main() {
// Variant is in position 16-17 (8th octet, high bits)
// Format: xxxxxxxx-xxxx-xxxx-Mxxx-xxxxxxxxxxxx
// M = 8, 9, a, b for RFC 4122 variant
// RFC 4122 variant (10xx = 8, 9, a, b)
let rfc = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
println!("Variant: {:?}", rfc.get_variant());
// Microsoft variant (110x = c, d, e, f)
let ms = Uuid::parse_str("550e8400-e29b-41d4-c716-446655440000").unwrap();
// Reserved variant (111x = f)
let reserved = Uuid::parse_str("550e8400-e29b-41d4-f716-446655440000").unwrap();
// parse_str accepts any variant
}parse_str accepts any variant; variant is parsed, not enforced.
use uuid::Uuid;
fn main() {
// Nil UUID (all zeros) is valid
let nil = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap();
assert!(nil.is_nil());
// Also valid in simple format
let nil_simple = Uuid::parse_str("00000000000000000000000000000000").unwrap();
assert!(nil_simple.is_nil());
// Can create directly
let nil_direct = Uuid::nil();
assert_eq!(nil, nil_direct);
}The nil UUID (all zeros) is valid and represents "no UUID".
use uuid::Uuid;
use std::fmt;
// Custom error wrapper for better error messages
#[derive(Debug)]
enum ParseError {
InvalidUuid(uuid::Error),
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ParseError::InvalidUuid(e) => write!(f, "Invalid UUID format: {}", e),
}
}
}
impl std::error::Error for ParseError {}
fn parse_user_id(input: &str) -> Result<Uuid, ParseError> {
Uuid::parse_str(input).map_err(ParseError::InvalidUuid)
}
fn main() -> Result<(), ParseError> {
let uuid = parse_user_id("550e8400-e29b-41d4-a716-446655440000")?;
println!("User ID: {}", uuid);
Ok(())
}Wrap uuid::Error for domain-specific error handling.
use uuid::Uuid;
fn main() {
let result = Uuid::parse_str("not-a-uuid");
if let Err(e) = result {
// Error implements Display and Debug
println!("Error: {}", e); // Human-readable
println!("Debug: {:?}", e); // Detailed info
// The error message describes what was expected
// "invalid length: expected 32 or 36 characters, found 10"
}
// Different errors give different messages
let err_length = Uuid::parse_str("550e8400").unwrap_err();
println!("Length error: {}", err_length);
let err_char = Uuid::parse_str("550e8400-g29b-41d4-a716-446655440000").unwrap_err();
println!("Character error: {}", err_char);
let err_group = Uuid::parse_str("550e8400e-29b-41d4-a716-446655440000").unwrap_err();
println!("Group error: {}", err_group);
}Error messages are descriptive and indicate the specific issue.
use uuid::Uuid;
fn main() {
// Mistake: Extra whitespace
let with_whitespace = Uuid::parse_str(" 550e8400-e29b-41d4-a716-446655440000");
assert!(with_whitespace.is_err());
// Mistake: Uppercase URN
let urn_upper = Uuid::parse_str("URN:UUID:550e8400-e29b-41d4-a716-446655440000");
// URN prefix should be lowercase
// Actually: "urn" prefix is case-insensitive, "uuid" should be lowercase
// Mistake: Wrong hyphen positions
let wrong_hyphens = Uuid::parse_str("550-e8400e-29b-41d4-a716-4466-55440000");
assert!(wrong_hyphens.is_err());
// Correct format reminder:
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
// 8-4-4-4-12 hex digits
}Common parsing errors include whitespace, wrong hyphen positions, and invalid characters.
use uuid::Uuid;
fn main() {
let valid_uuid = "550e8400-e29b-41d4-a716-446655440000";
// parse_str validates and constructs
let start = std::time::Instant::now();
for _ in 0..100_000 {
let _ = Uuid::parse_str(valid_uuid);
}
println!("parse_str: {:?}", start.elapsed());
// If you have bytes already, use from_bytes (no parsing)
let bytes: [u8; 16] = [
0x55, 0x0e, 0x84, 0x00, 0xe2, 0x9b, 0x41, 0xd4,
0xa7, 0x16, 0x44, 0x66, 0x55, 0x44, 0x00, 0x00,
];
let start = std::time::Instant::now();
for _ in 0..100_000 {
let _ = Uuid::from_bytes(bytes);
}
println!("from_bytes: {:?}", start.elapsed());
// from_bytes is faster because it skips validation
}from_bytes is faster than parse_str but requires valid bytes.
Validation process:
Error types:
InvalidLength: Wrong number of charactersInvalidCharacter: Non-hex character foundInvalidGroup: Hyphen in wrong positionAccepted formats:
550e8400-e29b-41d4-a716-446655440000550e8400e29b41d4a716446655440000{550e8400-e29b-41d4-a716-446655440000}urn:uuid:550e8400-e29b-41d4-a716-446655440000Best practices:
parse_str for untrusted inputfrom_bytes when you control the input sourceUuid::nil() for the special nil UUID caseVersion and variant: parse_str accepts any version (0-15) and variant values—they are parsed and accessible via get_version() and get_variant(), but not enforced during parsing.