Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved parser & diagnostics #560

Merged
merged 2 commits into from Nov 13, 2021

Conversation

QnnOkabayashi
Copy link
Contributor

@QnnOkabayashi QnnOkabayashi commented Nov 11, 2021

I'm submitting a feature

Description

This features adds drastically improved diagnostics for error handling for the uuid!() macro. Improvements include not panicking on multibyte characters, and providing more human-oriented feedback on why a string failed to parse. For example, instead of complaining about an invalid length if the last group has one too many characters, it will tell you that the last group has one too many characters.

This PR also improves the parser implementation. It works by separating the parsing from error handling, allowing the parser to be a const fn that is heavily optimized and returns Option<[u8; 16]>, where the error handler can come along later and figure out exactly what went wrong if the user cares. This is because most of the time, it's likely that the user doesn't particularly care what went wrong because they aren't expecting it to fail.

Finally, it introduces the Uuid::try_parse method, which is intended to replace Uuid::parse_str. They do the same thing, except Uuid::parse_str will automatically diagnose the error with slight overhead in the case that it fails, where Uuid::try_parse just returns the lightweight error type, InvalidUuid, that can be diagnosed at a later time using InvalidUuid::into_err.

Related Issue(s)

#559
#556

@kinggoesgaming
Copy link
Member

@kinggoesgaming kinggoesgaming commented Nov 11, 2021

Would love to see the benchmarks on this

@QnnOkabayashi
Copy link
Contributor Author

@QnnOkabayashi QnnOkabayashi commented Nov 11, 2021

Would love to see the benchmarks on this

I'm not sure how to benchmark, but the implementation is a slightly modified version of the const-str impl.

#556 (comment)

benchmark violin plot

@KodrAus
Copy link
Member

@KodrAus KodrAus commented Nov 13, 2021

I think @kinggoesgaming would be interested in the difference with main, and it looks like things do improve there:

main

test parse_invalid_character ... bench:          44 ns/iter (+/- 1)
test parse_invalid_group_len ... bench:          60 ns/iter (+/- 1)
test parse_invalid_groups    ... bench:          71 ns/iter (+/- 1)
test parse_invalid_len       ... bench:          10 ns/iter (+/- 0)
test parse_nil               ... bench:          63 ns/iter (+/- 3)
test parse_nil_hyphenated    ... bench:          65 ns/iter (+/- 2)
test parse_random            ... bench:          56 ns/iter (+/- 3)
test parse_random_hyphenated ... bench:          65 ns/iter (+/- 2)
test parse_urn               ... bench:          67 ns/iter (+/- 2)

This PR

test parse_invalid_character ... bench:          47 ns/iter (+/- 0)
test parse_invalid_group_len ... bench:          55 ns/iter (+/- 0)
test parse_invalid_groups    ... bench:          62 ns/iter (+/- 0)
test parse_invalid_len       ... bench:          58 ns/iter (+/- 0)
test parse_nil               ... bench:          30 ns/iter (+/- 0)
test parse_nil_hyphenated    ... bench:          31 ns/iter (+/- 0)
test parse_random            ... bench:          30 ns/iter (+/- 0)
test parse_random_hyphenated ... bench:          31 ns/iter (+/- 0)
test parse_urn               ... bench:          32 ns/iter (+/- 0)

Copy link
Member

@KodrAus KodrAus left a comment

Thanks for working on this @QnnOkabayashi! This looks good to me 🚀

@KodrAus KodrAus merged commit b9c4a08 into uuid-rs:main Nov 13, 2021
19 checks passed
@QnnOkabayashi QnnOkabayashi deleted the fix-uuid-macro-diagnostics branch Nov 13, 2021
@kinggoesgaming
Copy link
Member

@kinggoesgaming kinggoesgaming commented Nov 14, 2021

I think @kinggoesgaming would be interested in the difference with main, and it looks like things do improve there:

main


test parse_invalid_character ... bench:          44 ns/iter (+/- 1)

test parse_invalid_group_len ... bench:          60 ns/iter (+/- 1)

test parse_invalid_groups    ... bench:          71 ns/iter (+/- 1)

test parse_invalid_len       ... bench:          10 ns/iter (+/- 0)

test parse_nil               ... bench:          63 ns/iter (+/- 3)

test parse_nil_hyphenated    ... bench:          65 ns/iter (+/- 2)

test parse_random            ... bench:          56 ns/iter (+/- 3)

test parse_random_hyphenated ... bench:          65 ns/iter (+/- 2)

test parse_urn               ... bench:          67 ns/iter (+/- 2)

This PR


test parse_invalid_character ... bench:          47 ns/iter (+/- 0)

test parse_invalid_group_len ... bench:          55 ns/iter (+/- 0)

test parse_invalid_groups    ... bench:          62 ns/iter (+/- 0)

test parse_invalid_len       ... bench:          58 ns/iter (+/- 0)

test parse_nil               ... bench:          30 ns/iter (+/- 0)

test parse_nil_hyphenated    ... bench:          31 ns/iter (+/- 0)

test parse_random            ... bench:          30 ns/iter (+/- 0)

test parse_random_hyphenated ... bench:          31 ns/iter (+/- 0)

test parse_urn               ... bench:          32 ns/iter (+/- 0)

Yup this is exactly what I was thinking about. The couple of regressions are IMHO acceptable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants