How does uuid::Uuid::parse_str validate and parse UUID strings in various formats?

uuid::Uuid::parse_str accepts multiple UUID string formatsβ€”simple (32 hex digits), hyphenated (canonical 8-4-4-4-12), braced, and URN-prefixedβ€”validating each character as hexadecimal and checking length constraints. The parser normalizes all valid formats to a consistent internal representation while rejecting malformed input with detailed error information.

Basic Parsing

use uuid::Uuid;
 
fn basic_parsing() {
    // Hyphenated format (canonical)
    let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    println!("Parsed: {}", uuid);
    
    // Simple format (no hyphens)
    let uuid = Uuid::parse_str("550e8400e29b41d4a716446655440000").unwrap();
    println!("Parsed: {}", uuid);
    
    // Both produce identical results:
    assert_eq!(
        Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(),
        Uuid::parse_str("550e8400e29b41d4a716446655440000").unwrap()
    );
}

The parser accepts both hyphenated and simple formats, producing identical Uuid values.

Supported Formats

use uuid::Uuid;
 
fn supported_formats() {
    // Format 1: Hyphenated (canonical, RFC 4122)
    let hyphenated = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000");
    assert!(hyphenated.is_ok());
    
    // Format 2: Simple (32 hex digits, no hyphens)
    let simple = Uuid::parse_str("550e8400e29b41d4a716446655440000");
    assert!(simple.is_ok());
    
    // Format 3: Braced (Microsoft-style)
    let braced = Uuid::parse_str("{550e8400-e29b-41d4-a716-446655440000}");
    assert!(braced.is_ok());
    
    // Format 4: URN (RFC 4122 URN namespace)
    let urn = Uuid::parse_str("urn:uuid:550e8400-e29b-41d4-a716-446655440000");
    assert!(urn.is_ok());
    
    // All produce the same UUID
    assert_eq!(hyphenated.unwrap(), simple.unwrap());
    assert_eq!(hyphenated.unwrap(), braced.unwrap());
    assert_eq!(hyphenated.unwrap(), urn.unwrap());
}

The parser handles four formats, all normalizing to the same UUID.

Format Detection and Parsing

use uuid::Uuid;
 
fn format_detection() {
    // The parser automatically detects format from prefix/content
    
    // No prefix = hyphenated or simple
    let uuid1 = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    
    // Brace prefix detected
    let uuid2 = Uuid::parse_str("{550e8400-e29b-41d4-a716-446655440000}").unwrap();
    
    // URN prefix detected
    let uuid3 = Uuid::parse_str("urn:uuid:550e8400-e29b-41d4-a716-446655440000").unwrap();
    
    // Parser strips prefix/brackets, then validates content
    assert_eq!(uuid1, uuid2);
    assert_eq!(uuid1, uuid3);
    
    // Format detection is case-insensitive
    let urn_upper = Uuid::parse_str("URN:UUID:550e8400-e29b-41d4-a716-446655440000");
    assert!(urn_upper.is_ok());
}

The parser detects format from prefixes and handles case-insensitive URN identifiers.

Hexadecimal Validation

use uuid::Uuid;
 
fn hexadecimal_validation() {
    // Valid: all hexadecimal characters
    let valid = Uuid::parse_str("550e8400e29b41d4a716446655440000");
    assert!(valid.is_ok());
    
    // Valid: uppercase hex
    let upper = Uuid::parse_str("550E8400E29B41D4A716446655440000");
    assert!(upper.is_ok());
    
    // Valid: mixed case
    let mixed = Uuid::parse_str("550e8400E29B41d4A716446655440000");
    assert!(mixed.is_ok());
    
    // Invalid: non-hex characters
    let invalid = Uuid::parse_str("550e8400e29b41d4a71644665544000g");
    // 'g' is not a valid hex character
    assert!(invalid.is_err());
    
    // Invalid: hyphen in wrong position (simple format)
    let bad_hyphen = Uuid::parse_str("550e8400e29b-41d4a716446655440000");
    // Hyphen in position 12 when not expected
    // This is actually invalid for simple format
}

Each character must be a valid hexadecimal digit (0-9, a-f, A-F) or a hyphen in expected positions.

Length Validation

use uuid::Uuid;
 
fn length_validation() {
    // Valid lengths:
    // - Simple: 32 hex digits
    // - Hyphenated: 32 hex digits + 4 hyphens = 36 chars
    // - Braced: 36 + 2 brackets = 38 chars
    // - URN: varies based on prefix
    
    // Correct simple format: 32 chars
    let simple = Uuid::parse_str("550e8400e29b41d4a716446655440000");
    assert!(simple.is_ok());
    
    // Too short: 31 chars
    let short = Uuid::parse_str("550e8400e29b41d4a71644665544000");
    assert!(short.is_err());
    
    // Too long: 33 chars
    let long = Uuid::parse_str("550e8400e29b41d4a7164466554400000");
    assert!(long.is_err());
    
    // Correct hyphenated: 36 chars
    let hyphenated = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000");
    assert!(hyphenated.is_ok());
    
    // Wrong hyphen positions
    let bad_positions = Uuid::parse_str("550e8400e-29b-41d4-a716-446655440000");
    assert!(bad_positions.is_err());
}

Length and hyphen positions are strictly validated for hyphenated format.

Hyphen Position Validation

use uuid::Uuid;
 
fn hyphen_positions() {
    // Canonical hyphenated format: 8-4-4-4-12
    // Hyphens at positions: 8, 13, 18, 23 (0-indexed)
    
    // Valid: hyphens in correct positions
    let valid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000");
    assert!(valid.is_ok());
    
    // Positions:  550e8400 - e29b - 41d4 - a716 - 446655440000
    // Index:      0      7 9   12 14  17 19  22 24           35
    
    // Invalid: missing hyphen
    let missing = Uuid::parse_str("550e8400e29b-41d4-a716-446655440000");
    assert!(missing.is_err());
    
    // Invalid: extra hyphen
    let extra = Uuid::parse_str("550e-8400-e29b-41d4-a716-446655440000");
    assert!(extra.is_err());
    
    // Invalid: wrong positions
    let wrong = Uuid::parse_str("550e8400e-29-b41d4a7164-446655440000");
    assert!(wrong.is_err());
}

Hyphens must appear at exact positions in hyphenated format.

Error Handling

use uuid::Uuid;
 
fn error_handling() {
    // parse_str returns Result<Uuid, Error>
    
    // Valid UUID
    match Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000") {
        Ok(uuid) => println!("Parsed: {}", uuid),
        Err(e) => println!("Error: {}", e),
    }
    
    // Invalid: non-hex character
    match Uuid::parse_str("550e8400-xxxx-41d4-a716-446655440000") {
        Ok(uuid) => println!("Parsed: {}", uuid),
        Err(e) => println!("Error: {}", e),
        // Output: Error: invalid character: expected an optional prefix of 
        //         `urn:uuid:` followed by [0-9a-fA-F-], found `x` at 9
    }
    
    // Invalid: wrong length
    match Uuid::parse_str("550e8400-e29b-41d4-a716") {
        Ok(uuid) => println!("Parsed: {}", uuid),
        Err(e) => println!("Error: {}", e),
        // Output: Error: invalid length: expected 32 characters for simple 
        //         format or 36 characters for hyphenated format
    }
    
    // Invalid: wrong hyphen positions
    match Uuid::parse_str("550e-8400-e29b-41d4-a716-446655440000") {
        Ok(uuid) => println!("Parsed: {}", uuid),
        Err(e) => println!("Error: {}", e),
    }
}

Error messages indicate the specific validation failure.

Case Insensitivity

use uuid::Uuid;
 
fn case_insensitivity() {
    // Lowercase
    let lower = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    
    // Uppercase
    let upper = Uuid::parse_str("550E8400-E29B-41D4-A716-446655440000").unwrap();
    
    // Mixed case
    let mixed = Uuid::parse_str("550e8400-E29b-41D4-a716-446655440000").unwrap();
    
    // All produce identical UUIDs
    assert_eq!(lower, upper);
    assert_eq!(lower, mixed);
    
    // Display format is lowercase by default
    println!("Display: {}", lower);  // lowercase
    
    // Hyphenated format preserved case-insensitively
    assert_eq!(lower.hyphenated().to_string(), "550e8400-e29b-41d4-a716-446655440000");
}

The parser is case-insensitive for hexadecimal characters and URN prefixes.

Braced Format Handling

use uuid::Uuid;
 
fn braced_format() {
    // Microsoft-style braced format
    let braced = Uuid::parse_str("{550e8400-e29b-41d4-a716-446655440000}").unwrap();
    let normal = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    
    assert_eq!(braced, normal);
    
    // Braces must be complete
    let no_close = Uuid::parse_str("{550e8400-e29b-41d4-a716-446655440000");
    assert!(no_close.is_err());
    
    let no_open = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000}");
    assert!(no_open.is_err());
    
    // Only hyphenated content inside braces
    let braced_simple = Uuid::parse_str("{550e8400e29b41d4a716446655440000}");
    // May or may not be accepted depending on version
    // Typically requires hyphenated format inside braces
}

Braced format expects hyphenated UUID content between { and }.

URN Format Handling

use uuid::Uuid;
 
fn urn_format() {
    // RFC 4122 URN format
    let urn = Uuid::parse_str("urn:uuid:550e8400-e29b-41d4-a716-446655440000").unwrap();
    let normal = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    
    assert_eq!(urn, normal);
    
    // Case-insensitive URN prefix
    let urn_upper = Uuid::parse_str("URN:UUID:550e8400-e29b-41d4-a716-446655440000");
    assert!(urn_upper.is_ok());
    
    let urn_mixed = Uuid::parse_str("Urn:Uuid:550e8400-e29b-41d4-a716-446655440000");
    assert!(urn_mixed.is_ok());
    
    // URN requires hyphenated UUID after prefix
    let urn_simple = Uuid::parse_str("urn:uuid:550e8400e29b41d4a716446655440000");
    // Typically requires hyphenated format after urn:uuid:
}

URN format strips the urn:uuid: prefix before parsing the UUID content.

Nil UUID Handling

use uuid::Uuid;
 
fn nil_uuid() {
    // Nil UUID: all zeros
    let nil_hyphenated = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap();
    let nil_simple = Uuid::parse_str("00000000000000000000000000000000").unwrap();
    
    assert_eq!(nil_hyphenated, nil_simple);
    assert!(nil_hyphenated.is_nil());
    
    // Can also use Uuid::nil()
    let nil_direct = Uuid::nil();
    assert_eq!(nil_hyphenated, nil_direct);
}

The nil UUID (all zeros) is parsed correctly in all formats.

UUID Version Handling

use uuid::Uuid;
 
fn version_handling() {
    // Version 4 (random) UUID
    let v4 = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    // Version is encoded in the UUID (bits 48-51 of time_hi_and_version)
    
    println!("Version: {:?}", v4.get_version());
    println!("Variant: {:?}", v4.get_variant());
    
    // Version digits: 4th segment starts with version
    // 550e8400-e29b-41d4-a716-446655440000
    //                    ^ 4 is version (random)
    
    // Valid versions: 1-7 (as of UUID specification)
    // Version bits must be valid
    
    // Any hex in version position is accepted for parsing
    // Version validation happens after parsing
    let custom = Uuid::parse_str("550e8400-e29b-c1d4-a716-446655440000");
    assert!(custom.is_ok());  // 'c' in version position
    
    // Variant bits also validated
    // RFC 4122 variant: 10xx in variant field
}

The parser accepts any valid hex; version and variant are informational.

Variant Validation

use uuid::Uuid;
 
fn variant_validation() {
    // Variant is encoded in certain bits
    // RFC 4122 variant: 10xx (most significant bits of clock_seq)
    
    let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    
    match uuid.get_variant() {
        Some(variant) => println!("Variant: {:?}", variant),
        None => println!("Unknown variant"),
    }
    
    // Valid variants:
    // - NCS (reserved)
    // - RFC 4122 (standard)
    // - Microsoft
    // - Future (reserved)
    
    // Parser accepts any variant bits
    // Use get_variant() to check after parsing
}

Variant bits are parsed and can be queried after successful parsing.

Performance Characteristics

use uuid::Uuid;
 
fn performance_characteristics() {
    // Parsing involves:
    // 1. Length check
    // 2. Format detection (prefix/brackets)
    // 3. Hex validation per character
    // 4. Hyphen position validation (if hyphenated)
    // 5. Conversion to bytes
    
    // Hyphenated format: 36 chars + validation
    // Simple format: 32 chars (slightly faster)
    
    // For hot paths, consider:
    // 1. Pre-validate once, store as Uuid
    // 2. Use Uuid::from_bytes if you have bytes
    
    // From bytes (no parsing overhead)
    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);
    
    // Parsing has overhead
    let parsed = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    
    assert_eq!(from_bytes, parsed);
}

For performance-critical code, use from_bytes to avoid parsing overhead.

Parsing Algorithm

use uuid::Uuid;
 
fn parsing_algorithm_explanation() {
    // Internal parsing steps:
    
    // 1. Trim and detect format
    //    - Check for "urn:uuid:" prefix (case-insensitive)
    //    - Check for '{' prefix (braced format)
    //    - Strip prefix and/or braces
    
    // 2. Determine format
    //    - Length 32: simple format
    //    - Length 36: hyphenated format
    //    - Other: invalid
    
    // 3. Validate characters
    //    - Simple: all must be hex digits
    //    - Hyphenated: hyphens at positions 8, 13, 18, 23
    //                 everything else must be hex
    
    // 4. Convert to bytes
    //    - Parse pairs of hex characters
    //    - Convert to 16 bytes
    
    // Example: "550e8400"
    // '5' '5' -> 0x55
    // '0' 'e' -> 0x0e
    // '8' '4' -> 0x84
    // '0' '0' -> 0x00
    // Result: [0x55, 0x0e, 0x84, 0x00]
    
    let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    let bytes = uuid.as_bytes();
    // bytes = [0x55, 0x0e, 0x84, 0x00, 0xe2, 0x9b, ...]
}

The parser converts hex pairs to bytes after validating format.

Alternative Parsing Methods

use uuid::Uuid;
 
fn alternative_parsing() {
    // parse_str: &str -> Result<Uuid, Error>
    let result = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000");
    
    // parse: Generic (supports String, etc.)
    let from_string = "550e8400-e29b-41d4-a716-446655440000".parse::<Uuid>();
    assert!(from_string.is_ok());
    
    // from_bytes: [u8; 16] -> Uuid (no validation)
    let bytes: [u8; 16] = [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_le: Little-endian bytes
    let from_bytes_le = Uuid::from_bytes_le(bytes);
    
    // from_u128: 128-bit integer -> Uuid
    let from_u128 = Uuid::from_u128(0x550e8400_e29b_41d4_a716_446655440000);
    
    // All produce same UUID (with different byte ordering for le)
}

Multiple construction methods provide flexibility based on data source.

Stricter Parsing with Features

use uuid::Uuid;
 
fn feature_flags() {
    // The uuid crate has optional features for stricter validation:
    
    // Default: Lenient parsing (accepts multiple formats)
    // - Simple (32 hex digits)
    // - Hyphenated (36 chars with hyphens)
    // - Braced (with {})
    // - URN (with urn:uuid: prefix)
    
    // Feature: stricter parsing may be available
    // Check crate documentation for feature flags
    
    // Standard format (RFC 4122): hyphenated
    let hyphenated = "550e8400-e29b-41d4-a716-446655440000";
    
    // For strict hyphenated-only, validate manually:
    fn parse_strict(s: &str) -> Result<Uuid, String> {
        if s.len() != 36 || !s.chars().enumerate().all(|(i, c)| {
            if i == 8 || i == 13 || i == 18 || i == 23 {
                c == '-'
            } else {
                c.is_ascii_hexdigit()
            }
        }) {
            return Err("Invalid UUID format".to_string());
        }
        Uuid::parse_str(s).map_err(|e| e.to_string())
    }
}

The default parser is lenient; manual validation enforces stricter format requirements.

Common Parsing Errors

use uuid::Uuid;
 
fn common_errors() {
    // Error: Invalid length (too short)
    let too_short = Uuid::parse_str("550e8400");
    assert!(too_short.is_err());
    
    // Error: Invalid length (too long)
    let too_long = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000-extra");
    assert!(too_long.is_err());
    
    // Error: Invalid character
    let bad_char = Uuid::parse_str("550e8400-xxxx-41d4-a716-446655440000");
    assert!(bad_char.is_err());
    
    // Error: Invalid hyphen position
    let bad_hyphen = Uuid::parse_str("550e-8400-e29b-41d4-a716-446655440000");
    assert!(bad_hyphen.is_err());
    
    // Error: Missing hyphen (expected hyphenated)
    let missing_hyphen = Uuid::parse_str("550e8400e29b41d4-a716-446655440000");
    // This might parse as invalid length or wrong format
    assert!(missing_hyphen.is_err());
    
    // Error: Empty string
    let empty = Uuid::parse_str("");
    assert!(empty.is_err());
    
    // Error: Only whitespace
    let whitespace = Uuid::parse_str("   ");
    assert!(whitespace.is_err());
    
    // Error: Missing closing brace
    let unclosed_brace = Uuid::parse_str("{550e8400-e29b-41d4-a716-446655440000");
    assert!(unclosed_brace.is_err());
}

Common errors include wrong length, invalid characters, and misplaced hyphens.

Real-World Usage Patterns

use uuid::Uuid;
use std::collections::HashMap;
 
struct User {
    id: Uuid,
    name: String,
}
 
fn real_world_patterns() {
    // Pattern 1: Parse user input
    fn parse_user_uuid(input: &str) -> Result<Uuid, String> {
        Uuid::parse_str(input).map_err(|e| format!("Invalid UUID: {}", e))
    }
    
    // Pattern 2: Database key
    let mut users: HashMap<Uuid, User> = HashMap::new();
    
    if let Ok(id) = parse_user_uuid("550e8400-e29b-41d4-a716-446655440000") {
        users.insert(id, User { id, name: "Alice".into() });
    }
    
    // Pattern 3: API deserialization (serde)
    // #[derive(Deserialize)]
    // struct Request {
    //     #[serde(deserialize_with = "Uuid::parse_str")]
    //     id: Uuid,
    // }
    
    // Pattern 4: Config file UUID
    fn load_config_uuid(config_value: &str) -> Uuid {
        Uuid::parse_str(config_value)
            .expect("Config must contain valid UUID")
    }
}

UUID parsing is common for user input, database keys, APIs, and configuration.

Display and Serialization

use uuid::Uuid;
 
fn display_serialization() {
    let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
    
    // Display: hyphenated lowercase
    println!("Display: {}", uuid);  // 550e8400-e29b-41d4-a716-446655440000
    
    // Hyphenated format
    let hyphenated = uuid.hyphenated();
    println!("Hyphenated: {}", hyphenated);
    
    // Simple format (no hyphens)
    let simple = uuid.simple();
    println!("Simple: {}", simple);  // 550e8400e29b41d4a716446655440000
    
    // URN format
    let urn = uuid.urn();
    println!("URN: {}", urn);  // urn:uuid:550e8400-e29b-41d4-a716-446655440000
    
    // Braced format
    let braced = uuid.braced();
    println!("Braced: {}", braced);  // {550e8400-e29b-41d4-a716-446655440000}
    
    // Upper case variants
    println!("Uppercase: {}", uuid.hyphenated().to_uppercase());
    // 550E8400-E29B-41D4-A716-446655440000
}

Parsed UUIDs can be formatted in any supported format.

Summary Table

fn summary_table() {
    // β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    // β”‚ Format          β”‚ Example                                    β”‚ Length β”‚
    // β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
    // β”‚ Simple          β”‚ 550e8400e29b41d4a716446655440000           β”‚ 32     β”‚
    // β”‚ Hyphenated      β”‚ 550e8400-e29b-41d4-a716-446655440000       β”‚ 36     β”‚
    // β”‚ Braced          β”‚ {550e8400-e29b-41d4-a716-446655440000}      β”‚ 38     β”‚
    // β”‚ URN             β”‚ urn:uuid:550e8400-e29b-41d4-a716-446655440000β”‚ 45     β”‚
    // β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    
    // β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    // β”‚ Validation Step      β”‚ Checks                                      β”‚
    // β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
    // β”‚ Length               β”‚ 32 (simple) or 36 (hyphenated) + prefix    β”‚
    // β”‚ Characters           β”‚ Hex digits (0-9, a-f, A-F)                 β”‚
    // β”‚ Hyphens              β”‚ Positions 8, 13, 18, 23 (hyphenated)      β”‚
    // β”‚ Braces               β”‚ Paired { } around content                   β”‚
    // β”‚ URN prefix           β”‚ "urn:uuid:" (case-insensitive)              β”‚
    // β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
}

Summary

fn key_points() {
    // β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    // β”‚ Aspect          β”‚ Behavior                                            β”‚
    // β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
    // β”‚ Formats         β”‚ Simple, hyphenated, braced, URN                      β”‚
    // β”‚ Case            β”‚ Case-insensitive for hex and URN                     β”‚
    // β”‚ Validation      β”‚ Length, characters, hyphen positions                 β”‚
    // β”‚ Errors          β”‚ Descriptive messages for failures                    β”‚
    // β”‚ Output          β”‚ Normalized Uuid type                               β”‚
    // β”‚ Performance     β”‚ Parsing has overhead; use from_bytes for speed      β”‚
    // β”‚ Display         β”‚ Multiple format options for output                  β”‚
    // β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    
    // Key points:
    // 1. parse_str accepts 4 formats: simple, hyphenated, braced, URN
    // 2. All formats normalize to identical Uuid values
    // 3. Hyphens must be at positions 8, 13, 18, 23 (hyphenated format)
    // 4. Simple format requires exactly 32 hex characters
    // 5. Parser is case-insensitive for hex characters
    // 6. URN prefix "urn:uuid:" is case-insensitive
    // 7. Braces must be paired { }
    // 8. Error messages indicate specific validation failure
    // 9. Use from_bytes() to avoid parsing overhead
    // 10. Display provides multiple output formats
}

Key insight: Uuid::parse_str is a lenient parser that accepts multiple common UUID string formatsβ€”simple (32 hex digits), hyphenated (RFC 4122 canonical format with hyphens at positions 8, 13, 18, 23), braced (Microsoft-style {uuid}), and URN-prefixed (urn:uuid:...)β€”normalizing all to a consistent Uuid value. The parser validates that non-hyphen characters are valid hexadecimal digits (case-insensitive), hyphens appear in correct positions, and total length matches expected format. For performance-critical paths where UUIDs are already in byte form, use Uuid::from_bytes or Uuid::from_u128 to skip parsing overhead entirely. The lenient parsing approach means you can accept UUIDs from various sources (user input, APIs, configuration files) without pre-formatting, but if you need strict format enforcement, validate format before parsing.