Skip to content

Commit

Permalink
add support for parsing UUIDs between braces
Browse files Browse the repository at this point in the history
  • Loading branch information
KodrAus committed Nov 1, 2021
1 parent 7b55e32 commit 9d06072
Show file tree
Hide file tree
Showing 5 changed files with 525 additions and 42 deletions.
46 changes: 46 additions & 0 deletions examples/windows_guid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,52 @@ fn guid_to_uuid() {
);
}

#[test]
#[cfg(windows)]
fn guid_to_uuid_le_encoded() {
use uuid::Uuid;
use winapi::shared::guiddef;

// A GUID might not be encoded directly as a UUID
// If its fields are stored in little-endian order they might
// need to be flipped. Whether or not this is necessary depends
// on the source of the GUID
let guid_in = guiddef::GUID {
Data1: 0x9d22354a,
Data2: 0x2755,
Data3: 0x304f,
Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8],
};

let uuid = Uuid::from_fields_le(
guid_in.Data1,
guid_in.Data2,
guid_in.Data3,
&guid_in.Data4,
);

let guid_out = {
let fields = uuid.to_fields_le();

guiddef::GUID {
Data1: fields.0,
Data2: fields.1,
Data3: fields.2,
Data4: *fields.3,
}
};

assert_eq!(
(guid_in.Data1, guid_in.Data2, guid_in.Data3, guid_in.Data4),
(
guid_out.Data1,
guid_out.Data2,
guid_out.Data3,
guid_out.Data4
)
);
}

#[test]
#[cfg(windows)]
fn uuid_from_cocreateguid() {
Expand Down
9 changes: 8 additions & 1 deletion shared/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,16 @@ pub fn parse_str(mut input: &str) -> Result<[u8; 16], Error> {
// Ensure length is valid for any of the supported formats
let len = input.len();

// Check for a URN prefixed UUID
if len == 45 && input.starts_with("urn:uuid:") {
input = &input[9..];
} else if !len_matches_any(len, &[36, 32]) {
}
// Check for a Microsoft GUID wrapped in {}
else if len == 38 && input.starts_with("{") && input.ends_with("}") {
input = &input[1..input.len() - 1];
}
// In other cases, check for a simple or hyphenated UUID
else if !len_matches_any(len, &[36, 32]) {
return Err(ErrorKind::InvalidLength {
expected: ExpectedLength::Any(&[36, 32]),
found: len,
Expand Down
30 changes: 29 additions & 1 deletion src/external/serde_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@

use crate::{
error::*,
fmt::{Hyphenated, HyphenatedRef, Simple, SimpleRef, Urn, UrnRef},
fmt::{
Braced, BracedRef, Hyphenated, HyphenatedRef, Simple, SimpleRef, Urn,
UrnRef,
},
std::fmt,
Uuid,
};
Expand Down Expand Up @@ -90,6 +93,24 @@ impl Serialize for UrnRef<'_> {
}
}

impl Serialize for Braced {
fn serialize<S: Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}

impl Serialize for BracedRef<'_> {
fn serialize<S: Serializer>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}

impl<'de> Deserialize<'de> for Uuid {
fn deserialize<D: Deserializer<'de>>(
deserializer: D,
Expand Down Expand Up @@ -240,6 +261,13 @@ mod serde_tests {
serde_test::assert_ser_tokens(&u.to_urn(), &[Token::Str(uuid_str)]);
}

#[test]
fn test_serialize_braced() {
let uuid_str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.to_braced(), &[Token::Str(uuid_str)]);
}

#[test]
fn test_serialize_compact() {
let uuid_bytes = b"F9168C5E-CEB2-4F";
Expand Down
Loading

0 comments on commit 9d06072

Please sign in to comment.