Skip to content

Commit

Permalink
Fixed and added more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
QnnOkabayashi committed Nov 2, 2021
1 parent 1414f2d commit 85c3dd7
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 21 deletions.
8 changes: 2 additions & 6 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,11 @@ pub fn parse_lit(input: TokenStream) -> TokenStream {
s.subspan(index + 1..=index + 1).unwrap()
}
Error::UuidParse(error::Error(
error::ErrorKind::InvalidGroupLength { found, group, .. },
error::ErrorKind::InvalidGroupLength { found, index, .. },
)) => {
let start =
parser::GROUP_LENS.iter().take(group).sum::<usize>()
+ group
+ 1;
let mut s = proc_macro2::Literal::string("");
s.set_span(ts.span());
s.subspan(start..start + found).unwrap()
s.subspan(index..index + found).unwrap()
}
_ => ts.span(),
};
Expand Down
3 changes: 3 additions & 0 deletions shared/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub(crate) enum ErrorKind {
found: usize,
/// The segment with invalid length.
group: usize,
/// The index of where the group starts
index: usize,
},
/// Invalid length of the [`Uuid`] string.
///
Expand Down Expand Up @@ -126,6 +128,7 @@ impl fmt::Display for Error {
ref expected,
found,
group,
..
} => write!(
f,
"expected {}, found {} in group {}",
Expand Down
22 changes: 17 additions & 5 deletions shared/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,24 @@ fn len_matches_any(len: usize, crits: &[usize]) -> bool {
const ACC_GROUP_LENS: [usize; 5] = [8, 12, 16, 20, 32];

// Length of each hyphenated group in hex digits.
pub(super) const GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12];
pub const GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12];

const URN_PREFIX: &str = "urn:uuid:";

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();

let mut start = 0;
// Check for a URN prefixed UUID
if len == 45 && input.starts_with("urn:uuid:") {
input = &input[9..];
if len == 45 && input.starts_with(URN_PREFIX) {
input = &input[URN_PREFIX.len()..];
start += URN_PREFIX.len();
}
// Check for a Microsoft GUID wrapped in {}
else if len == 38 && input.starts_with("{") && input.ends_with("}") {
input = &input[1..input.len() - 1];
start += 1;
}
// In other cases, check for a simple or hyphenated UUID
else if !len_matches_any(len, &[36, 32]) {
Expand Down Expand Up @@ -90,10 +95,13 @@ pub fn parse_str(mut input: &str) -> Result<[u8; 16], Error> {
digit
};

let index =
ACC_GROUP_LENS[group - 1] + group + 1 + start;
return Err(ErrorKind::InvalidGroupLength {
expected: ExpectedLength::Exact(GROUP_LENS[group]),
found: found as usize,
group,
index,
}
.into());
}
Expand All @@ -106,7 +114,7 @@ pub fn parse_str(mut input: &str) -> Result<[u8; 16], Error> {
return Err(ErrorKind::InvalidCharacter {
expected: "0123456789abcdefABCDEF-",
found: input[i_char..].chars().next().unwrap(),
index: i_char,
index: i_char + start,
urn: UrnPrefix::Optional,
}
.into());
Expand All @@ -127,18 +135,20 @@ pub fn parse_str(mut input: &str) -> Result<[u8; 16], Error> {
digit
};

let index = ACC_GROUP_LENS[group - 1] + group + 1 + start;
return Err(ErrorKind::InvalidGroupLength {
expected: ExpectedLength::Exact(GROUP_LENS[group]),
found: found as usize,
group,
index,
}
.into());
}
_ => {
return Err(ErrorKind::InvalidCharacter {
expected: "0123456789abcdefABCDEF-",
found: input[i_char..].chars().next().unwrap(),
index: i_char,
index: i_char + start,
urn: UrnPrefix::Optional,
}
.into());
Expand All @@ -151,10 +161,12 @@ pub fn parse_str(mut input: &str) -> Result<[u8; 16], Error> {

// Now check the last group.
if ACC_GROUP_LENS[4] as u8 != digit {
let index = ACC_GROUP_LENS[group - 1] + group + 1 + start;
return Err(ErrorKind::InvalidGroupLength {
expected: ExpectedLength::Exact(GROUP_LENS[4]),
found: (digit as usize - ACC_GROUP_LENS[3]),
group,
index,
}
.into());
}
Expand Down
4 changes: 4 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ mod tests {
expected: ExpectedLength::Exact(4),
found: 3,
group: 1,
index: 10,
}))
);
// (group, found, expecting)
Expand All @@ -231,6 +232,7 @@ mod tests {
expected: ExpectedLength::Exact(12),
found: 8,
group: 4,
index: 25,
}))
);

Expand Down Expand Up @@ -307,6 +309,7 @@ mod tests {
expected: ExpectedLength::Exact(8),
found: 6,
group: 0,
index: 1,
}))
);
assert_eq!(
Expand All @@ -315,6 +318,7 @@ mod tests {
expected: ExpectedLength::Exact(4),
found: 5,
group: 3,
index: 20,
}))
);
}
Expand Down
7 changes: 6 additions & 1 deletion tests/ui/compile_fail/invalid_parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const _: Uuid = uuid!("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4");
const _: Uuid = uuid!("01020304-1112-2122-3132-41424344");
const _: Uuid = uuid!("67e5504410b1426f9247bb680e5fe0c88");
const _: Uuid = uuid!("67e5504410b1426f9247bb680e5fe0cg8");
const _: Uuid = uuid!("67e5504410b1426%9247bb680e5fe0c8");
const _: Uuid = uuid!("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8");

// Test error reporting
const _: Uuid = uuid!("67e5504410b1426f9247bb680e5fe0c");
Expand All @@ -25,5 +25,10 @@ const _: Uuid = uuid!("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4");
const _: Uuid = uuid!("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");
const _: Uuid = uuid!("01020304-1112-2122-3132-41424344");
const _: Uuid = uuid!("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4");
const _: Uuid = uuid!("urn:uuid:F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");
const _: Uuid = uuid!("urn:uuid:F9168C5E-CEB2-4faa-B2cBF-32BF39FA1E4");
const _: Uuid = uuid!("{F9168C5E-CEB2-4faa-B0a75-32BF39FA1E4}");

const _: Uuid = uuid!("{F9168C5E-CEB2-4faa-B6BF-329Bz39FA1E4}");

fn main() {}
39 changes: 30 additions & 9 deletions tests/ui/compile_fail/invalid_parse.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ error: invalid length: expected one of [36, 32], found 33
14 | const _: Uuid = uuid!("67e5504410b1426f9247bb680e5fe0cg8");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid character: expected an optional prefix of `urn:uuid:` followed by 0123456789abcdefABCDEF-, found % at 15
--> tests/ui/compile_fail/invalid_parse.rs:15:39
|
15 | const _: Uuid = uuid!("67e5504410b1426%9247bb680e5fe0c8");
| ^

error: invalid length: expected one of [36, 32], found 31
--> tests/ui/compile_fail/invalid_parse.rs:18:23
|
Expand All @@ -88,11 +82,14 @@ error: invalid character: expected an optional prefix of `urn:uuid:` followed by
19 | const _: Uuid = uuid!("67e550X410b1426f9247bb680e5fe0cd");
| ^

error: invalid group length: expected 8, found 6 in group 0
--> tests/ui/compile_fail/invalid_parse.rs:20:24
error: proc macro panicked
--> tests/ui/compile_fail/invalid_parse.rs:20:17
|
20 | const _: Uuid = uuid!("67e550-4105b1426f9247bb680e5fe0c");
| ^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: message: attempt to subtract with overflow
= note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info)

error: invalid group length: expected 4, found 5 in group 3
--> tests/ui/compile_fail/invalid_parse.rs:21:43
Expand Down Expand Up @@ -123,3 +120,27 @@ error: invalid number of groups: expected one of [1, 5], found 4
|
27 | const _: Uuid = uuid!("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: invalid character: expected an optional prefix of `urn:uuid:` followed by 0123456789abcdefABCDEF-, found G at 29
--> tests/ui/compile_fail/invalid_parse.rs:28:53
|
28 | const _: Uuid = uuid!("urn:uuid:F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");
| ^

error: invalid group length: expected 4, found 5 in group 3
--> tests/ui/compile_fail/invalid_parse.rs:29:52
|
29 | const _: Uuid = uuid!("urn:uuid:F9168C5E-CEB2-4faa-B2cBF-32BF39FA1E4");
| ^^^^^

error: invalid group length: expected 4, found 5 in group 3
--> tests/ui/compile_fail/invalid_parse.rs:30:44
|
30 | const _: Uuid = uuid!("{F9168C5E-CEB2-4faa-B0a75-32BF39FA1E4}");
| ^^^^^

error: invalid character: expected an optional prefix of `urn:uuid:` followed by 0123456789abcdefABCDEF-, found z at 29
--> tests/ui/compile_fail/invalid_parse.rs:32:53
|
32 | const _: Uuid = uuid!("{F9168C5E-CEB2-4faa-B6BF-329Bz39FA1E4}");
| ^

0 comments on commit 85c3dd7

Please sign in to comment.