Implement custom q value parser according to spec#10
Implement custom q value parser according to spec#10maxcountryman merged 1 commit intomaxcountryman:mainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
Implements a new QValue type to parse and compare HTTP quality values according to the RFC specification, replacing the previous f32-based logic.
- Replaces
f32quality fields withQValueand updates comparisons inbest_matchand sorting routines. - Adds a
QValuestruct withFromStr,Ord, and utility methods plus comprehensive unit tests. - Refactors
parse_q_valueto returnQValuewithunwrap_or_default()for missing parameters.
Comments suppressed due to low confidence (3)
src/lib.rs:156
- Add a unit test for
Accept::best_matchor equivalent that verifies media types withq=0are correctly excluded by this branch.
if quality.is_zero() {
src/lib.rs:215
- Introduce a test that confirms media types are sorted by specificity and then by
QValue, to ensure the newsort_by_keybehavior matches expectations.
media_types.sort_by_key(|x| {
src/lib.rs:224
- [nitpick] The method name
parse_q_valuenow returns aQValuetype instead off32; consider renaming it toparse_qvalueor updating its doc comment to reflect the new return type more clearly.
fn parse_q_value(media_type: &MediaTypeBuf) -> QValue {
| fn parse_fractional(digits: &[u8]) -> Result<u16, HeaderError> { | ||
| digits | ||
| .iter() | ||
| .try_fold(0u16, |acc, &c| { | ||
| if c.is_ascii_digit() { | ||
| Some(acc * 10 + (c - b'0') as u16) | ||
| } else { | ||
| None | ||
| } | ||
| }) | ||
| .map(|num| match digits.len() { | ||
| 1 => num * 100, | ||
| 2 => num * 10, | ||
| _ => num, | ||
| }) | ||
| .ok_or_else(HeaderError::invalid) | ||
| } | ||
|
|
There was a problem hiding this comment.
[nitpick] Consider extracting the nested parse_fractional function out of the FromStr impl into a private helper at module scope for clarity and easier unit testing.
| fn parse_fractional(digits: &[u8]) -> Result<u16, HeaderError> { | |
| digits | |
| .iter() | |
| .try_fold(0u16, |acc, &c| { | |
| if c.is_ascii_digit() { | |
| Some(acc * 10 + (c - b'0') as u16) | |
| } else { | |
| None | |
| } | |
| }) | |
| .map(|num| match digits.len() { | |
| 1 => num * 100, | |
| 2 => num * 10, | |
| _ => num, | |
| }) | |
| .ok_or_else(HeaderError::invalid) | |
| } |
There was a problem hiding this comment.
Could also inline the function since it is only called once
There was a problem hiding this comment.
I'm not putting a lot of stock in what the AI says, I'm mostly just curious if it's at all intelligent.
|
Thanks for this. We can cut a new release inclusive of this and the last patch. I'll bump the minor version since this is technically breaking and we're not yet 1.0. |
|
Sure, thanks! |
No description provided.