From 6c984068a26b0096a0489dbaa2fa47c160e7e4fd Mon Sep 17 00:00:00 2001 From: Hyxogen <8938732+Hyxogen@users.noreply.github.com> Date: Tue, 28 Feb 2023 19:05:22 +0100 Subject: [PATCH 1/4] Replace Host::IPv4/6 with variant taking IpAddr --- url/src/host.rs | 48 ++++++++++++++++++++++++----------------------- url/src/lib.rs | 15 +++++---------- url/tests/unit.rs | 18 +++++++++--------- 3 files changed, 39 insertions(+), 42 deletions(-) diff --git a/url/src/host.rs b/url/src/host.rs index f1921c654..99491c57f 100644 --- a/url/src/host.rs +++ b/url/src/host.rs @@ -8,7 +8,7 @@ use std::cmp; use std::fmt::{self, Formatter}; -use std::net::{Ipv4Addr, Ipv6Addr}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use percent_encoding::{percent_decode, utf8_percent_encode, CONTROLS}; #[cfg(feature = "serde")] @@ -30,8 +30,8 @@ impl From> for HostInternal { match host { Host::Domain(ref s) if s.is_empty() => HostInternal::None, Host::Domain(_) => HostInternal::Domain, - Host::Ipv4(address) => HostInternal::Ipv4(address), - Host::Ipv6(address) => HostInternal::Ipv6(address), + Host::Ip(IpAddr::V4(address)) => HostInternal::Ipv4(address), + Host::Ip(IpAddr::V6(address)) => HostInternal::Ipv6(address), } } } @@ -45,18 +45,12 @@ pub enum Host { /// a special URL, or percent encoded for non-special URLs. Hosts for /// non-special URLs are also called opaque hosts. Domain(S), - - /// An IPv4 address. - /// `Url::host_str` returns the serialization of this address, - /// as four decimal integers separated by `.` dots. - Ipv4(Ipv4Addr), - - /// An IPv6 address. - /// `Url::host_str` returns the serialization of that address between `[` and `]` brackets, - /// in the format per [RFC 5952 *A Recommendation - /// for IPv6 Address Text Representation*](https://tools.ietf.org/html/rfc5952): + /// Either an IPv4 or IPv6 address. `Url::host_str` returns the serializatin of this address, + /// either as four decimal integers separated by `.` dots for an IPv4 address, or an address + /// between [ and ] brackets, in the format per [RFC 5952 *A Recommendation for IPv6 Address + /// Text Representation*](https://tools.ietf.org/html/rfc5952): /// lowercase hexadecimal with maximal `::` compression. - Ipv6(Ipv6Addr), + Ip(IpAddr), } impl<'a> Host<&'a str> { @@ -64,12 +58,17 @@ impl<'a> Host<&'a str> { pub fn to_owned(&self) -> Host { match *self { Host::Domain(domain) => Host::Domain(domain.to_owned()), - Host::Ipv4(address) => Host::Ipv4(address), - Host::Ipv6(address) => Host::Ipv6(address), + Host::Ip(address) => Host::Ip(address), } } } +impl From for Host { + fn from(address: IpAddr) -> Self { + Host::Ip(address) + } +} + impl Host { /// Parse a host: either an IPv6 address in [] square brackets, or a domain. /// @@ -79,7 +78,9 @@ impl Host { if !input.ends_with(']') { return Err(ParseError::InvalidIpv6Address); } - return parse_ipv6addr(&input[1..input.len() - 1]).map(Host::Ipv6); + return parse_ipv6addr(&input[1..input.len() - 1]) + .map(IpAddr::V6) + .map(|x| x.into()); } let domain = percent_decode(input.as_bytes()).decode_utf8_lossy(); @@ -115,7 +116,7 @@ impl Host { Err(ParseError::InvalidDomainCharacter) } else if ends_in_a_number(&domain) { let address = parse_ipv4addr(&domain)?; - Ok(Host::Ipv4(address)) + Ok(Host::Ip(IpAddr::V4(address))) } else { Ok(Host::Domain(domain)) } @@ -127,7 +128,9 @@ impl Host { if !input.ends_with(']') { return Err(ParseError::InvalidIpv6Address); } - return parse_ipv6addr(&input[1..input.len() - 1]).map(Host::Ipv6); + return parse_ipv6addr(&input[1..input.len() - 1]) + .map(IpAddr::V6) + .map(|x| x.into()); } let is_invalid_host_char = |c| { @@ -171,8 +174,8 @@ impl> fmt::Display for Host { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match *self { Host::Domain(ref domain) => domain.as_ref().fmt(f), - Host::Ipv4(ref addr) => addr.fmt(f), - Host::Ipv6(ref addr) => { + Host::Ip(IpAddr::V4(ref addr)) => addr.fmt(f), + Host::Ip(IpAddr::V6(ref addr)) => { f.write_str("[")?; write_ipv6(addr, f)?; f.write_str("]") @@ -188,8 +191,7 @@ where fn eq(&self, other: &Host) -> 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, + (Host::Ip(a), Host::Ip(b)) => a == b, (_, _) => false, } } diff --git a/url/src/lib.rs b/url/src/lib.rs index 0be004e6f..071eb1d8b 100644 --- a/url/src/lib.rs +++ b/url/src/lib.rs @@ -653,7 +653,7 @@ impl Url { HostInternal::None => assert_eq!(host_str, ""), HostInternal::Ipv4(address) => assert_eq!(host_str, address.to_string()), HostInternal::Ipv6(address) => { - let h: Host = Host::Ipv6(address); + let h: Host = Host::Ip(address.into()); assert_eq!(host_str, h.to_string()) } HostInternal::Domain => { @@ -1086,8 +1086,8 @@ impl Url { match self.host { HostInternal::None => None, HostInternal::Domain => Some(Host::Domain(self.slice(self.host_start..self.host_end))), - HostInternal::Ipv4(address) => Some(Host::Ipv4(address)), - HostInternal::Ipv6(address) => Some(Host::Ipv6(address)), + HostInternal::Ipv4(address) => Some(Host::Ip(address.into())), + HostInternal::Ipv6(address) => Some(Host::Ip(address.into())), } } @@ -1232,8 +1232,7 @@ impl Url { )?; Ok(match host { Host::Domain(domain) => (domain, port).to_socket_addrs()?.collect(), - Host::Ipv4(ip) => vec![(ip, port).into()], - Host::Ipv6(ip) => vec![(ip, port).into()], + Host::Ip(ip) => vec![(ip, port).into()], }) } @@ -2022,11 +2021,7 @@ impl Url { return Err(()); } - let address = match address { - IpAddr::V4(address) => Host::Ipv4(address), - IpAddr::V6(address) => Host::Ipv6(address), - }; - self.set_host_internal(address, None); + self.set_host_internal(address.into(), None); Ok(()) } diff --git a/url/tests/unit.rs b/url/tests/unit.rs index d27016b37..9c74566c2 100644 --- a/url/tests/unit.rs +++ b/url/tests/unit.rs @@ -267,28 +267,28 @@ fn host() { assert_host("http://www.mozilla.org", Host::Domain("www.mozilla.org")); assert_host( "http://1.35.33.49", - Host::Ipv4(Ipv4Addr::new(1, 35, 33, 49)), + Host::Ip(Ipv4Addr::new(1, 35, 33, 49).into()), ); assert_host( "http://[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]", - Host::Ipv6(Ipv6Addr::new( + Host::Ip(Ipv6Addr::new( 0x2001, 0x0db8, 0x85a3, 0x08d3, 0x1319, 0x8a2e, 0x0370, 0x7344, - )), + ).into()), ); assert_host( "http://[::]", - Host::Ipv6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), + Host::Ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).into()), ); assert_host( "http://[::1]", - Host::Ipv6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), + Host::Ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).into()), ); assert_host( "http://0x1.0X23.0x21.061", - Host::Ipv4(Ipv4Addr::new(1, 35, 33, 49)), + Host::Ip(Ipv4Addr::new(1, 35, 33, 49).into()), ); - assert_host("http://0x1232131", Host::Ipv4(Ipv4Addr::new(1, 35, 33, 49))); - assert_host("http://111", Host::Ipv4(Ipv4Addr::new(0, 0, 0, 111))); + assert_host("http://0x1232131", Host::Ip(Ipv4Addr::new(1, 35, 33, 49).into())); + assert_host("http://111", Host::Ip(Ipv4Addr::new(0, 0, 0, 111).into())); assert!(Url::parse("http://1.35.+33.49").is_err()); assert!(Url::parse("http://2..2.3").is_err()); assert!(Url::parse("http://42.0x1232131").is_err()); @@ -780,7 +780,7 @@ fn test_windows_unc_path() { assert_eq!(url.as_str(), "file://xn--hst-sna/share/path/file.txt"); let url = Url::from_file_path(Path::new(r"\\192.168.0.1\share\path\file.txt")).unwrap(); - assert_eq!(url.host(), Some(Host::Ipv4(Ipv4Addr::new(192, 168, 0, 1)))); + assert_eq!(url.host(), Some(Host::Ip(Ipv4Addr::new(192, 168, 0, 1).into()))); let path = url.to_file_path().unwrap(); assert_eq!(path.to_str(), Some(r"\\192.168.0.1\share\path\file.txt")); From 48a6cbcdb2a866bd25594b95f685fd2576416872 Mon Sep 17 00:00:00 2001 From: Hyxogen <8938732+Hyxogen@users.noreply.github.com> Date: Tue, 28 Feb 2023 19:10:39 +0100 Subject: [PATCH 2/4] Replace T with S to be more consistent --- url/src/host.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/url/src/host.rs b/url/src/host.rs index 99491c57f..7c3f67bc4 100644 --- a/url/src/host.rs +++ b/url/src/host.rs @@ -63,7 +63,7 @@ impl<'a> Host<&'a str> { } } -impl From for Host { +impl From for Host { fn from(address: IpAddr) -> Self { Host::Ip(address) } From c4803ad20845efa55eca117310b4bf429ca45bd1 Mon Sep 17 00:00:00 2001 From: Hyxogen <8938732+Hyxogen@users.noreply.github.com> Date: Tue, 28 Feb 2023 19:37:07 +0100 Subject: [PATCH 3/4] Make code style more consistent --- url/src/host.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/url/src/host.rs b/url/src/host.rs index 7c3f67bc4..665f4f9d2 100644 --- a/url/src/host.rs +++ b/url/src/host.rs @@ -80,7 +80,7 @@ impl Host { } return parse_ipv6addr(&input[1..input.len() - 1]) .map(IpAddr::V6) - .map(|x| x.into()); + .map(From::from); } let domain = percent_decode(input.as_bytes()).decode_utf8_lossy(); From 8355aaed0c354b3422448e96d2a52395c142819b Mon Sep 17 00:00:00 2001 From: Hyxogen <8938732+Hyxogen@users.noreply.github.com> Date: Tue, 28 Feb 2023 19:38:20 +0100 Subject: [PATCH 4/4] Format code --- url/tests/unit.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/url/tests/unit.rs b/url/tests/unit.rs index 9c74566c2..8b877170c 100644 --- a/url/tests/unit.rs +++ b/url/tests/unit.rs @@ -271,9 +271,12 @@ fn host() { ); assert_host( "http://[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]", - Host::Ip(Ipv6Addr::new( - 0x2001, 0x0db8, 0x85a3, 0x08d3, 0x1319, 0x8a2e, 0x0370, 0x7344, - ).into()), + Host::Ip( + Ipv6Addr::new( + 0x2001, 0x0db8, 0x85a3, 0x08d3, 0x1319, 0x8a2e, 0x0370, 0x7344, + ) + .into(), + ), ); assert_host( "http://[::]", @@ -287,7 +290,10 @@ fn host() { "http://0x1.0X23.0x21.061", Host::Ip(Ipv4Addr::new(1, 35, 33, 49).into()), ); - assert_host("http://0x1232131", Host::Ip(Ipv4Addr::new(1, 35, 33, 49).into())); + assert_host( + "http://0x1232131", + Host::Ip(Ipv4Addr::new(1, 35, 33, 49).into()), + ); assert_host("http://111", Host::Ip(Ipv4Addr::new(0, 0, 0, 111).into())); assert!(Url::parse("http://1.35.+33.49").is_err()); assert!(Url::parse("http://2..2.3").is_err()); @@ -780,7 +786,10 @@ fn test_windows_unc_path() { assert_eq!(url.as_str(), "file://xn--hst-sna/share/path/file.txt"); let url = Url::from_file_path(Path::new(r"\\192.168.0.1\share\path\file.txt")).unwrap(); - assert_eq!(url.host(), Some(Host::Ip(Ipv4Addr::new(192, 168, 0, 1).into()))); + assert_eq!( + url.host(), + Some(Host::Ip(Ipv4Addr::new(192, 168, 0, 1).into())) + ); let path = url.to_file_path().unwrap(); assert_eq!(path.to_str(), Some(r"\\192.168.0.1\share\path\file.txt"));