// Copyright 2013-2014 The Rust Project Developers. // Copyright 2018 The Uuid Project Developers. // // See the COPYRIGHT file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms.
//! [`Uuid`] parsing constructs and utilities. //! //! [`Uuid`]: ../struct.Uuid.html
impl Uuid { /// Parses a `Uuid` from a string of hexadecimal digits with optional /// hyphens. /// /// Any of the formats generated by this module (simple, hyphenated, urn, /// Microsoft GUID) are supported by this parsing function. /// /// Prefer [`try_parse`] unless you need detailed user-facing diagnostics. /// This method will be eventually deprecated in favor of `try_parse`. /// /// # Examples /// /// Parse a hyphenated UUID: /// /// ``` /// # use uuid::{Uuid, Version, Variant}; /// # fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?; /// /// assert_eq!(Some(Version::Random), uuid.get_version()); /// assert_eq!(Variant::RFC4122, uuid.get_variant()); /// # Ok(()) /// # } /// ``` /// /// [`try_parse`]: #method.try_parse pubfn parse_str(input: &str) -> Result<Uuid, Error> {
try_parse(input.as_bytes())
.map(Uuid::from_bytes)
.map_err(InvalidUuid::into_err)
}
/// Parses a `Uuid` from a string of hexadecimal digits with optional /// hyphens. /// /// This function is similar to [`parse_str`], in fact `parse_str` shares /// the same underlying parser. The difference is that if `try_parse` /// fails, it won't generate very useful error messages. The `parse_str` /// function will eventually be deprecated in favor or `try_parse`. /// /// To parse a UUID from a byte stream instead of a UTF8 string, see /// [`try_parse_ascii`]. /// /// # Examples /// /// Parse a hyphenated UUID: /// /// ``` /// # use uuid::{Uuid, Version, Variant}; /// # fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000")?; /// /// assert_eq!(Some(Version::Random), uuid.get_version()); /// assert_eq!(Variant::RFC4122, uuid.get_variant()); /// # Ok(()) /// # } /// ``` /// /// [`parse_str`]: #method.parse_str /// [`try_parse_ascii`]: #method.try_parse_ascii pubconstfn try_parse(input: &str) -> Result<Uuid, Error> { Self::try_parse_ascii(input.as_bytes())
}
/// Parses a `Uuid` from a string of hexadecimal digits with optional /// hyphens. /// /// The input is expected to be a string of ASCII characters. This method /// can be more convenient than [`try_parse`] if the UUID is being /// parsed from a byte stream instead of from a UTF8 string. /// /// # Examples /// /// Parse a hyphenated UUID: /// /// ``` /// # use uuid::{Uuid, Version, Variant}; /// # fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::try_parse_ascii(b"550e8400-e29b-41d4-a716-446655440000")?; /// /// assert_eq!(Some(Version::Random), uuid.get_version()); /// assert_eq!(Variant::RFC4122, uuid.get_variant()); /// # Ok(()) /// # } /// ``` /// /// [`try_parse`]: #method.try_parse pubconstfn try_parse_ascii(input: &[u8]) -> Result<Uuid, Error> { match try_parse(input) {
Ok(bytes) => Ok(Uuid::from_bytes(bytes)), // If parsing fails then we don't know exactly what went wrong // In this case, we just return a generic error
Err(_) => Err(Error(ErrorKind::Other)),
}
}
}
constfn try_parse(input: &[u8]) -> Result<[u8; 16], InvalidUuid> { let result = match (input.len(), input) { // Inputs of 32 bytes must be a non-hyphenated UUID
(32, s) => parse_simple(s), // Hyphenated UUIDs may be wrapped in various ways: // - `{UUID}` for braced UUIDs // - `urn:uuid:UUID` for URNs // - `UUID` for a regular hyphenated UUID
(36, s)
| (38, [b'{', s @ .., b'}'])
| (45, [b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..]) => {
parse_hyphenated(s)
} // Any other shaped input is immediately invalid
_ => Err(()),
};
match result {
Ok(b) => Ok(b),
Err(()) => Err(InvalidUuid(input)),
}
}
#[inline] constfn parse_simple(s: &[u8]) -> Result<[u8; 16], ()> { // This length check here removes all other bounds // checks in this function if s.len() != 32 { return Err(());
}
letmut buf: [u8; 16] = [0; 16]; letmut i = 0;
while i < 16 { // Convert a two-char hex value (like `A8`) // into a byte (like `10101000`) let h1 = HEX_TABLE[s[i * 2] as usize]; let h2 = HEX_TABLE[s[i * 2 + 1] as usize];
// We use `0xff` as a sentinel value to indicate // an invalid hex character sequence (like the letter `G`) if h1 | h2 == 0xff { return Err(());
}
// The upper nibble needs to be shifted into position // to produce the final byte value
buf[i] = SHL4_TABLE[h1 as usize] | h2;
i += 1;
}
Ok(buf)
}
#[inline] constfn parse_hyphenated(s: &[u8]) -> Result<[u8; 16], ()> { // This length check here removes all other bounds // checks in this function if s.len() != 36 { return Err(());
}
// We look at two hex-encoded values (4 chars) at a time because // that's the size of the smallest group in a hyphenated UUID. // The indexes we're interested in are: // // uuid : 936da01f-9abd-4d9d-80c7-02af85c822a8 // | | || || || || | | // hyphens : | | 8| 13| 18| 23| | | // positions: 0 4 9 14 19 24 28 32
// First, ensure the hyphens appear in the right places match [s[8], s[13], s[18], s[23]] {
[b'-', b'-', b'-', b'-'] => {}
_ => return Err(()),
}
// The decoding here is the same as the simple case // We're just dealing with two values instead of one let h1 = HEX_TABLE[s[i as usize] as usize]; let h2 = HEX_TABLE[s[(i + 1) as usize] as usize]; let h3 = HEX_TABLE[s[(i + 2) as usize] as usize]; let h4 = HEX_TABLE[s[(i + 3) as usize] as usize];
#[cfg(test)] mod tests { usesuper::*; usecrate::{std::string::ToString, tests::new};
#[test] fn test_parse_uuid_v4_valid() { let from_hyphenated = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap(); let from_simple = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8").unwrap(); let from_urn = Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap(); let from_guid = Uuid::parse_str("{67e55044-10b1-426f-9247-bb680e5fe0c8}").unwrap();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.