From d369611e982b064dfc8539da91c20f7b67e74b02 Mon Sep 17 00:00:00 2001 From: "Adam C. Foltzer" Date: Fri, 28 Aug 2020 14:28:44 -0700 Subject: [PATCH] url: add TryFrom<&[u8]> for Url and TryFrom tests Per [discussion on Matrix](https://matrix.to/#/!wurHQemAfsdBxUYHeU:mozilla.org/$MLu4rFb7uBI54AT4-UwKZSyEMXELJRM7Rqm1dpGZ6kM?via=mozilla.org&via=matrix.org). I didn't realize when first asking that `TryFrom<&str>` is already implemented, but hasn't been released. So, I ended up just adding the impl for byte slices, an error variant for invalid UTF-8 inputs, and tests for the impls. --- url/src/lib.rs | 9 +++++++++ url/src/parser.rs | 1 + url/tests/unit.rs | 18 +++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/url/src/lib.rs b/url/src/lib.rs index f9830f272..4e24b20ef 100644 --- a/url/src/lib.rs +++ b/url/src/lib.rs @@ -2339,6 +2339,15 @@ impl<'a> TryFrom<&'a str> for Url { } } +impl<'a> TryFrom<&'a [u8]> for Url { + type Error = ParseError; + + fn try_from(bytes: &'a [u8]) -> Result { + let s = std::str::from_utf8(bytes).map_err(|_| ParseError::InvalidUtf8)?; + Url::parse(s) + } +} + /// Display the serialization of this URL. impl fmt::Display for Url { #[inline] diff --git a/url/src/parser.rs b/url/src/parser.rs index be7992e00..47150265d 100644 --- a/url/src/parser.rs +++ b/url/src/parser.rs @@ -87,6 +87,7 @@ simple_enum_error! { InvalidIpv4Address => "invalid IPv4 address", InvalidIpv6Address => "invalid IPv6 address", InvalidDomainCharacter => "invalid domain character", + InvalidUtf8 => "invalid UTF-8", RelativeUrlWithoutBase => "relative URL without a base", RelativeUrlWithCannotBeABaseBase => "relative URL with a cannot-be-a-base base", SetHostOnCannotBeABaseUrl => "a cannot-be-a-base URL doesn’t have a host to set", diff --git a/url/tests/unit.rs b/url/tests/unit.rs index adaa54de6..e9b4bba69 100644 --- a/url/tests/unit.rs +++ b/url/tests/unit.rs @@ -10,9 +10,10 @@ use std::borrow::Cow; use std::cell::{Cell, RefCell}; +use std::convert::TryFrom; use std::net::{Ipv4Addr, Ipv6Addr}; use std::path::{Path, PathBuf}; -use url::{form_urlencoded, Host, Url}; +use url::{form_urlencoded, Host, ParseError, Url}; #[test] fn size() { @@ -169,6 +170,21 @@ fn from_str() { assert!("http://testing.com/this".parse::().is_ok()); } +#[test] +fn try_from_str() { + assert!(Url::try_from("http://testing.com/this").is_ok()); +} + +#[test] +fn try_from_slice() { + assert!(Url::try_from(&b"http://testing.com/this"[..]).is_ok()); +} + +#[test] +fn try_from_slice_invalid_utf8() { + assert!(Url::try_from(&[0, 159, 146, 150][..]) == Err(ParseError::InvalidUtf8)); +} + #[test] fn parse_with_params() { let url = Url::parse_with_params(