Repository: servo/rust-url
Pull request #651 (2020-11-21 18:24:46)

Generalize PartialEq impl for Host
This allows `Host<String>` to be compared with a `Host<&str>`, for example.

mbrubeck: I included commits to fix existing CI failures on the master branch.  I can drop these or separate them into different PR(s) if desired.

Patch:
diff --git a/data-url/src/mime.rs b/data-url/src/mime.rs
index 8219ace..5840a2c 100644
--- a/data-url/src/mime.rs
+++ b/data-url/src/mime.rs
@@ -62,6 +62,7 @@ fn split2(s: &str, separator: char) -> (&str, Option<&str>) {
     (first, iter.next())
 }
 
+#[allow(clippy::manual_strip)] // introduced in 1.45, MSRV is 1.36
 fn parse_parameters(s: &str, parameters: &mut Vec<(String, String)>) {
     let mut semicolon_separated = s.split(';');
 
diff --git a/idna/src/punycode.rs b/idna/src/punycode.rs
index cc7f664..07445cd 100644
--- a/idna/src/punycode.rs
+++ b/idna/src/punycode.rs
@@ -164,7 +164,7 @@ where
     }
 
     if basic_length > 0 {
-        output.push_str("-")
+        output.push('-')
     }
     let mut code_point = INITIAL_N;
     let mut delta = 0;
diff --git a/idna/src/uts46.rs b/idna/src/uts46.rs
index 37c1963..90e47a8 100644
--- a/idna/src/uts46.rs
+++ b/idna/src/uts46.rs
@@ -298,6 +298,7 @@ fn is_valid(label: &str, config: Config) -> bool {
 }
 
 /// http://www.unicode.org/reports/tr46/#Processing
+#[allow(clippy::manual_strip)] // introduced in 1.45, MSRV is 1.36
 fn processing(domain: &str, config: Config) -> (String, Errors) {
     // Weed out the simple cases: only allow all lowercase ASCII characters and digits where none
     // of the labels start with PUNYCODE_PREFIX and labels don't start or end with hyphen.
diff --git a/url/src/host.rs b/url/src/host.rs
index c91215f..3bdbc47 100644
--- a/url/src/host.rs
+++ b/url/src/host.rs
@@ -38,7 +38,7 @@ impl From<Host<String>> for HostInternal {
 
 /// The host name of an URL.
 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
-#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Clone, Debug, Eq, Ord, PartialOrd, Hash)]
 pub enum Host<S = String> {
     /// A DNS domain name, as '.' dot-separated labels.
     /// Non-ASCII labels are encoded in punycode per IDNA if this is the host of
@@ -172,6 +172,20 @@ impl<S: AsRef<str>> fmt::Display for Host<S> {
     }
 }
 
+impl<S, T> PartialEq<Host<T>> for Host<S>
+where
+    S: PartialEq<T>,
+{
+    fn eq(&self, other: &Host<T>) -> bool {
+        match (self, other) {
+            (Host::Domain(a), Host::Domain(b)) => a == b,
+            (Host::Ipv4(a), Host::Ipv4(b)) => a == b,
+            (Host::Ipv6(a), Host::Ipv6(b)) => a == b,
+            (_, _) => false,
+        }
+    }
+}
+
 fn write_ipv6(addr: &Ipv6Addr, f: &mut Formatter<'_>) -> fmt::Result {
     let segments = addr.segments();
     let (compress_start, compress_end) = longest_zero_sequence(&segments);
diff --git a/url/src/lib.rs b/url/src/lib.rs
index 3d491b6..cdb8cba 100644
--- a/url/src/lib.rs
+++ b/url/src/lib.rs
@@ -1092,6 +1092,7 @@ impl Url {
     /// # }
     /// # run().unwrap();
     /// ```
+    #[allow(clippy::manual_strip)] // introduced in 1.45, MSRV is 1.36
     pub fn path_segments(&self) -> Option<str::Split<'_, char>> {
         let path = self.path();
         if path.starts_with('/') {


Test patch:
diff --git a/url/tests/unit.rs b/url/tests/unit.rs
index adaa54d..21a7194 100644
--- a/url/tests/unit.rs
+++ b/url/tests/unit.rs
@@ -274,6 +274,9 @@ fn host() {
     assert_host("http://2..2.3", Host::Domain("2..2.3"));
     assert!(Url::parse("http://42.0x1232131").is_err());
     assert!(Url::parse("http://192.168.0.257").is_err());
+
+    assert_eq!(Host::Domain("foo"), Host::Domain("foo").to_owned());
+    assert_ne!(Host::Domain("foo"), Host::Domain("bar").to_owned());
 }
 
 #[test]