http
http copied to clipboard
Implement PartialOrd and Ord for http::Uri
I thought about an implementation like this
impl PartialOrd for Uri {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Uri {
fn cmp(&self, other: &Self) -> Ordering {
if self.eq(other) {
Ordering::Equal
} else {
(self.scheme(), self.authority(), self.path_and_query())
.cmp(&(other.scheme(), other.authority(), other.path_and_query()))
}
}
}
the problem is the components only implement PartialOrd
.
Another option would be:
impl PartialOrd for Uri {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Uri {
fn cmp(&self, other: &Self) -> Ordering {
if self.eq(other) {
Ordering::Equal
} else {
self.to_string().cmp(other.to_string())
}
}
}
Do you have a use case in mind for this? Could you share?
Do you have a use case in mind for this? Could you share?
Deriving the PartialOrd and Ord traits on types that contain the http::Uri
type?
Do those types of yours suggest any particular ordering for the Uri
component? What I'm (just a contributor) looking for is if there is a particularly natural ordering. For example, compared to your first suggested Ord
impl, I might have chosen:
(self.authority().host(), self.authority().port(), self.scheme(), self.path_and_query())
...in that order, as being more natural.
As far as I remember, there was no particular reason, why I proposed the above implementation. It was meant as a suggestion, how this could be implemented.
I think it does not even matter that the ordering makes sense (for my use case), because I only wanted it, so I do not have to implement PartialEq, Eq, PartialOrd, Ord and Hash manually for the structs that use http::Uri internally. (All the trait implementations have to agree with each other).
I am not very familiar with this crate, so I do not know if your ordering is more natural, but my proposal would work with crates that use http::Uri
conditionally and fallback to String
. (The ordering for http::Uri
would be equivalent to its String
equivalent)
Authority
currently does a case-insensitive host PartialOrd
which is different then ordering the output of to_string()
. That might suggest this ordering is more consistent than my original suggestion:
(self.authority(), self.scheme(), self.path_and_query())
As far as implementation, it might be better to avoid the conditional for Eq
:
impl PartialOrd for Uri {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Uri {
fn cmp(&self, r: &Self) -> Ordering {
(self.authority(), self.scheme(), self.path_and_query())
.cmp(&(r.authority(), r.scheme(), r.path_and_query()))
}
}
...unless I'm missing something about that?
Users can still new-type the Uri
(or Authority
) to achieve alternative PartialOrd
/Ord
.