Implement IntoUrl for String (#1201)

Also change from blanket impl to improve docs.
This commit is contained in:
Ibraheem Ahmed
2021-03-01 18:50:29 -05:00
committed by GitHub
parent ff2381e61e
commit 9fa58e316d
2 changed files with 28 additions and 16 deletions

View File

@@ -3,21 +3,23 @@ use url::Url;
/// A trait to try to convert some type into a `Url`. /// A trait to try to convert some type into a `Url`.
/// ///
/// This trait is "sealed", such that only types within reqwest can /// This trait is "sealed", such that only types within reqwest can
/// implement it. The reason is that it will eventually be deprecated /// implement it.
/// and removed, when `std::convert::TryFrom` is stabilized. pub trait IntoUrl: IntoUrlSealed {}
pub trait IntoUrl: PolyfillTryInto {}
impl<T: PolyfillTryInto> IntoUrl for T {} impl IntoUrl for Url {}
impl IntoUrl for String {}
impl<'a> IntoUrl for &'a str {}
impl<'a> IntoUrl for &'a String {}
pub trait PolyfillTryInto { pub trait IntoUrlSealed {
// Besides parsing as a valid `Url`, the `Url` must be a valid // Besides parsing as a valid `Url`, the `Url` must be a valid
// `http::Uri`, in that it makes sense to use in a network request. // `http::Uri`, in that it makes sense to use in a network request.
fn into_url(self) -> crate::Result<Url>; fn into_url(self) -> crate::Result<Url>;
fn _as_str(&self) -> &str; fn as_str(&self) -> &str;
} }
impl PolyfillTryInto for Url { impl IntoUrlSealed for Url {
fn into_url(self) -> crate::Result<Url> { fn into_url(self) -> crate::Result<Url> {
if self.has_host() { if self.has_host() {
Ok(self) Ok(self)
@@ -26,27 +28,37 @@ impl PolyfillTryInto for Url {
} }
} }
fn _as_str(&self) -> &str { fn as_str(&self) -> &str {
self.as_ref() self.as_ref()
} }
} }
impl<'a> PolyfillTryInto for &'a str { impl<'a> IntoUrlSealed for &'a str {
fn into_url(self) -> crate::Result<Url> { fn into_url(self) -> crate::Result<Url> {
Url::parse(self).map_err(crate::error::builder)?.into_url() Url::parse(self).map_err(crate::error::builder)?.into_url()
} }
fn _as_str(&self) -> &str { fn as_str(&self) -> &str {
self.as_ref() self
} }
} }
impl<'a> PolyfillTryInto for &'a String { impl<'a> IntoUrlSealed for &'a String {
fn into_url(self) -> crate::Result<Url> { fn into_url(self) -> crate::Result<Url> {
(&**self).into_url() (&**self).into_url()
} }
fn _as_str(&self) -> &str { fn as_str(&self) -> &str {
self.as_ref()
}
}
impl<'a> IntoUrlSealed for String {
fn into_url(self) -> crate::Result<Url> {
(&*self).into_url()
}
fn as_str(&self) -> &str {
self.as_ref() self.as_ref()
} }
} }

View File

@@ -3,7 +3,7 @@ use std::fmt;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc; use std::sync::Arc;
use crate::into_url::{IntoUrl, PolyfillTryInto}; use crate::into_url::{IntoUrl, IntoUrlSealed};
use crate::Url; use crate::Url;
use http::{header::HeaderValue, Uri}; use http::{header::HeaderValue, Uri};
use ipnet::IpNet; use ipnet::IpNet;
@@ -111,11 +111,11 @@ pub trait IntoProxyScheme {
impl<S: IntoUrl> IntoProxyScheme for S { impl<S: IntoUrl> IntoProxyScheme for S {
fn into_proxy_scheme(self) -> crate::Result<ProxyScheme> { fn into_proxy_scheme(self) -> crate::Result<ProxyScheme> {
// validate the URL // validate the URL
let url = match self._as_str().into_url() { let url = match self.as_str().into_url() {
Ok(ok) => ok, Ok(ok) => ok,
Err(e) => { Err(e) => {
// the issue could have been caused by a missing scheme, so we try adding http:// // the issue could have been caused by a missing scheme, so we try adding http://
format!("http://{}", self._as_str()) format!("http://{}", self.as_str())
.into_url() .into_url()
.map_err(|_| { .map_err(|_| {
// return the original error // return the original error