pub fn parse(guid: &str) -> Result<GUID, String>
    {
        // We support the following formats:
        //
        // - {00000000-0000-0000-0000-000000000000} (38 chars)
        // - 00000000-0000-0000-0000-000000000000 (36 chars)
        // - 00000000000000000000000000000000 (32 chars)
        //
        // Use the total length to make the assumption on the format.
        enum GuidFormat
        {
            Braces,
            Hyphens,
            Raw,
        }
        let guid_format = match guid.len() {
            38 => GuidFormat::Braces,
            36 => GuidFormat::Hyphens,
            32 => GuidFormat::Raw,
            _ => {
                return Err(format!(
                    "Unrecognized GUID format: '{}' ({})",
                    guid,
                    guid.len()
                ))
            }
        };

        // Define the format requirements.
        //
        // Some(_) values correspond to required characters while None values
        // correspond to the hexadecimal digits themselves.
        #[rustfmt::skip]
        let format = match guid_format {
            GuidFormat::Braces => vec![
                Some( b'{' ), None, None, None, None, None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None, None, None, None, None, None, None, None, None,
                Some( b'}' )
            ],
            GuidFormat::Hyphens => vec![
                None, None, None, None, None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None, None, None, None, None, None, None, None, None
            ],
            GuidFormat::Raw => vec![
                None, None, None, None, None, None, None, None,
                None, None, None, None,
                None, None, None, None,
                None, None, None, None,
                None, None, None, None, None, None, None, None, None, None, None, None
            ]
        };

        // Read the hexadecimal values into a buffer.
        let mut buffer = [0u8; 16];
        let mut digit = 0;
        for (i_char, chr) in guid.bytes().enumerate() {
            // If this is a fixed character, ensure we have the correct one.
            // If we had the correct char, continue onto next character,
            // otherwise error out. In any case we'll go past this guard
            // only if we're expeting a hexadecimal-digit.
            if let Some(b) = format[i_char] {
                if chr == b {
                    continue;
                } else {
                    return Err(format!("Unexpected character in GUID: {}", chr));
                }
            }

            // Convert the hexadecimal character into a numerical value.
            let value: u8 = match chr {
                b'0'..=b'9' => chr - b'0',
                b'a'..=b'f' => chr - b'a' + 10,
                b'A'..=b'F' => chr - b'A' + 10,
                _ => return Err(format!("Unrecognized character in GUID: {}", chr)),
            };

            // Each digit corresponds to one half of a byte in the final [u8]
            // buffer. Resolve which half and which byte this is.
            let half = digit % 2;
            let byte = (digit - half) / 2;

            // Finally add the value into the buffer and proceed to the next
            // digit.
            if half == 0 {
                buffer[byte] += value * 16;
            } else {
                buffer[byte] += value;
            }

            // 'digit' is incremented only when we actually match a hex-digit
            // in the GUID. 'i_char', which is the loop counter, also includes
            // all the GUID formatting characters, such as {} and -.
            digit += 1;
        }

        // We got the whole buffer. Convert it into a GUID.
        //
        // Note: We could probably do this with a memcopy - we might have even
        // been able to do it directly into the GUID by preallocating it and
        // then interpreting it as a *[u8] array.
        //
        // However I can't be bothered to figure out endianness bits here, so
        // we'll just go with raw calculations.
        Ok(GUID {
            data1: (u32::from(buffer[0]) << 24)
                + (u32::from(buffer[1]) << 16)
                + (u32::from(buffer[2]) << 8)
                + (u32::from(buffer[3])),
            data2: (u16::from(buffer[4]) << 8) + (u16::from(buffer[5])),
            data3: (u16::from(buffer[6]) << 8) + (u16::from(buffer[7])),
            data4: [
                buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14],
                buffer[15],
            ],
        })
    }
/// Parses the given string as a GUID.
///
/// Supported formats include:
///
/// - Braces and hyphens: {00000000-0000-0000-0000-000000000000}
/// - Hyphens only: 00000000-0000-0000-0000-000000000000
/// - Raw hexadecimal: 00000000000000000000000000000000
Parses the given string as a GUID.
Supported formats include.


Parses the given string as a GUID . Supported formats include .
pub fn parse(guid: &str) -> Result<GUID, String>
    {
        // We support the following formats:
        //
        // - {00000000-0000-0000-0000-000000000000} (38 chars)
        // - 00000000-0000-0000-0000-000000000000 (36 chars)
        // - 00000000000000000000000000000000 (32 chars)
        //
        // Use the total length to make the assumption on the format.
        enum GuidFormat
        {
            Braces,
            Hyphens,
            Raw,
        }
        let guid_format = match guid.len() {
            38 => GuidFormat::Braces,
            36 => GuidFormat::Hyphens,
            32 => GuidFormat::Raw,
            _ => {
                return Err(format!(
                    "Unrecognized GUID format: '{}' ({})",
                    guid,
                    guid.len()
                ))
            }
        };
        // Define the format requirements.
        //
        // Some(_) values correspond to required characters while None values
        // correspond to the hexadecimal digits themselves.
        #[rustfmt::skip]
        let format = match guid_format {
            GuidFormat::Braces => vec![
                Some( b'{' ), None, None, None, None, None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None, None, None, None, None, None, None, None, None,
                Some( b'}' )
            ],
            GuidFormat::Hyphens => vec![
                None, None, None, None, None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None,
                Some( b'-' ), None, None, None, None, None, None, None, None, None, None, None, None
            ],
            GuidFormat::Raw => vec![
                None, None, None, None, None, None, None, None,
                None, None, None, None,
                None, None, None, None,
                None, None, None, None,
                None, None, None, None, None, None, None, None, None, None, None, None
            ]
        };
        // Read the hexadecimal values into a buffer.
        let mut buffer = [0u8; 16];
        let mut digit = 0;
        for (i_char, chr) in guid.bytes().enumerate() {
            // If this is a fixed character, ensure we have the correct one.
            // If we had the correct char, continue onto next character,
            // otherwise error out. In any case we'll go past this guard
            // only if we're expeting a hexadecimal-digit.
            if let Some(b) = format[i_char] {
                if chr == b {
                    continue;
                } else {
                    return Err(format!("Unexpected character in GUID: {}", chr));
                }
            }
            // Convert the hexadecimal character into a numerical value.
            let value: u8 = match chr {
                b'0'..=b'9' => chr - b'0',
                b'a'..=b'f' => chr - b'a' + 10,
                b'A'..=b'F' => chr - b'A' + 10,
                _ => return Err(format!("Unrecognized character in GUID: {}", chr)),
            };
            // Each digit corresponds to one half of a byte in the final [u8]
            // buffer. Resolve which half and which byte this is.
            let half = digit % 2;
            let byte = (digit - half) / 2;
            // Finally add the value into the buffer and proceed to the next
            // digit.
            if half == 0 {
                buffer[byte] += value * 16;
            } else {
                buffer[byte] += value;
            }
            // 'digit' is incremented only when we actually match a hex-digit
            // in the GUID. 'i_char', which is the loop counter, also includes
            // all the GUID formatting characters, such as {} and -.
            digit += 1;
        }
        // We got the whole buffer. Convert it into a GUID.
        //
        // Note: We could probably do this with a memcopy - we might have even
        // been able to do it directly into the GUID by preallocating it and
        // then interpreting it as a *[u8] array.
        //
        // However I can't be bothered to figure out endianness bits here, so
        // we'll just go with raw calculations.
        Ok(GUID {
            data1: (u32::from(buffer[0]) << 24)
                + (u32::from(buffer[1]) << 16)
                + (u32::from(buffer[2]) << 8)
                + (u32::from(buffer[3])),
            data2: (u16::from(buffer[4]) << 8) + (u16::from(buffer[5])),
            data3: (u16::from(buffer[6]) << 8) + (u16::from(buffer[7])),
            data4: [
                buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14],
                buffer[15],
            ],
        })
    }
pub fn parse ( guid : & str ) -> Result < GUID , String > { // We support the following formats: // // - {00000000-0000-0000-0000-000000000000} (38 chars) // - 00000000-0000-0000-0000-000000000000 (36 chars) // - 00000000000000000000000000000000 (32 chars) // // Use the total length to make the assumption on the format. enum GuidFormat { Braces , Hyphens , Raw , } let guid_format = match guid . len ( ) { 38 => GuidFormat :: Braces , 36 => GuidFormat :: Hyphens , 32 => GuidFormat :: Raw , _ => { return Err ( format ! ( " " guid guid len ( ) ) ) } } ; // Define the format requirements. // // Some(_) values correspond to required characters while None values // correspond to the hexadecimal digits themselves. # [ rustfmt :: skip ] let format = match guid_format { GuidFormat :: Braces => vec ! [ Some ( b'{' ) None None None None None None None None Some ( b'-' ) None None None None Some ( b'-' ) None None None None Some ( b'-' ) None None None None Some ( b'-' ) None None None None None None None None None None None None Some ( b'}' ) ] , GuidFormat :: Hyphens => vec ! [ None None None None None None None None Some ( b'-' ) None None None None Some ( b'-' ) None None None None Some ( b'-' ) None None None None Some ( b'-' ) None None None None None None None None None None None None ] , GuidFormat :: Raw => vec ! [ None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None ] } ; // Read the hexadecimal values into a buffer. let mut buffer = [ 0u8 ; 16 ] ; let mut digit = 0 ; for ( i_char , chr ) in guid . bytes ( ) . enumerate ( ) { // If this is a fixed character, ensure we have the correct one. // If we had the correct char, continue onto next character, // otherwise error out. In any case we'll go past this guard // only if we're expeting a hexadecimal-digit. if let Some ( b ) = format [ i_char ] { if chr == b { continue ; } else { return Err ( format ! ( " " chr ) ) ; } } // Convert the hexadecimal character into a numerical value. let value : u8 = match chr { b'0' ..= b'9' => chr - b'0' , b'a' ..= b'f' => chr - b'a' + 10 , b'A' ..= b'F' => chr - b'A' + 10 , _ => return Err ( format ! ( " " chr ) ) , } ; // Each digit corresponds to one half of a byte in the final [u8] // buffer. Resolve which half and which byte this is. let half = digit % 2 ; let byte = ( digit - half ) / 2 ; // Finally add the value into the buffer and proceed to the next // digit. if half == 0 { buffer [ byte ] += value * 16 ; } else { buffer [ byte ] += value ; } // 'digit' is incremented only when we actually match a hex-digit // in the GUID. 'i_char', which is the loop counter, also includes // all the GUID formatting characters, such as {} and -. digit += 1 ; } // We got the whole buffer. Convert it into a GUID. // // Note: We could probably do this with a memcopy - we might have even // been able to do it directly into the GUID by preallocating it and // then interpreting it as a *[u8] array. // // However I can't be bothered to figure out endianness bits here, so // we'll just go with raw calculations. Ok ( GUID { data1 : ( u32 :: from ( buffer [ 0 ] ) << 24 ) + ( u32 :: from ( buffer [ 1 ] ) << 16 ) + ( u32 :: from ( buffer [ 2 ] ) << 8 ) + ( u32 :: from ( buffer [ 3 ] ) ) , data2 : ( u16 :: from ( buffer [ 4 ] ) << 8 ) + ( u16 :: from ( buffer [ 5 ] ) ) , data3 : ( u16 :: from ( buffer [ 6 ] ) << 8 ) + ( u16 :: from ( buffer [ 7 ] ) ) , data4 : [ buffer [ 8 ] , buffer [ 9 ] , buffer [ 10 ] , buffer [ 11 ] , buffer [ 12 ] , buffer [ 13 ] , buffer [ 14 ] , buffer [ 15 ] , ] , } ) }
Parses the given string as a GUID.
Parses the given string as a GUID .
guid
&str
guid
&str