-
Notifications
You must be signed in to change notification settings - Fork 788
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
Fixes #3328 Order[ContentCoding] should depend on compareToIgnoreCase #3501
Fixes #3328 Order[ContentCoding] should depend on compareToIgnoreCase #3501
Conversation
Order.from { | ||
case (a, b) if a.coding.compareToIgnoreCase(b.coding) == 0 => a.qValue.compare(b.qValue) | ||
case (a, b) => a.coding.compareToIgnoreCase(b.coding) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is right (I haven't rerun the test with the seed), but you could avoid repeating the comparison when codings aren't equal. I think this is also right:
Order.from { | |
case (a, b) if a.coding.compareToIgnoreCase(b.coding) == 0 => a.qValue.compare(b.qValue) | |
case (a, b) => a.coding.compareToIgnoreCase(b.coding) | |
} | |
val cmp = a.coding.compareToIgnoreCase(b.coding) | |
if (cmp == 0) a.qValue.compare(b.qValue) else cmp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rossabaker this does not work. The test fails with that seed value. Will change the PR to WIP and investigate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nuts. Maybe I misanalyzed it on the ticket. If we can figure out the exact inputs to that failing case, and not just the .toString
representation, it should be much easier to spot that error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened a PR after investigating deeper myself, but after that, I think this might still be correct. We just don't have an example where it matters, because characters are restricted to token characters, none of which do weird things in case folding.
@@ -114,7 +115,8 @@ object ContentCoding { | |||
} | |||
|
|||
implicit val http4sOrderForContentCoding: Order[ContentCoding] = | |||
Order.by(c => (c.coding.toLowerCase, c.qValue)) | |||
Order.by(c => (c.coding.toLowerCase(ju.Locale.ENGLISH), c.qValue)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Maybe. compareToIgnoreCase
is character-by-character, like equalIgnoreCase
, so I'm having a hard time conceptualizing why that wouldn't work. toLowerCase
can change the lengths of the strings, and I fear is open to more corner cases. And the default locale on my machine is en_US
anyway.
If we're going to use .toLowerCase
, I agree with this change, to not rely on the default locale. It still doesn't feel right, but I don't have a counterexample.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rossabaker checkout #3328 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would still use compareToIgnoreCase, but shouldn't matter for the legal codings, isn't significantly more performant at the length of codings we'll see in practice, and will be refactored to a CIString
in 1.0. As is, this protects us against default locales that none of us have heard of.
No description provided.