use std::error::Error;
use std::fmt;
use std::fmt::{Display, Formatter};
use http::Uri;
use url::Url;
#[derive(Debug)]
pub enum UrlToUriError {
InvalidAuthority,
InvalidHost,
Http(http::Error),
}
impl Display for UrlToUriError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
UrlToUriError::InvalidAuthority => f.write_str("invalid authority"),
UrlToUriError::InvalidHost => f.write_str("invalid host"),
UrlToUriError::Http(error) => error.fmt(f),
}
}
}
impl Error for UrlToUriError {}
pub fn url_to_uri(url: &Url) -> Result<Uri, UrlToUriError> {
if !url.has_authority() {
return Err(UrlToUriError::InvalidAuthority);
}
if !url.has_host() {
return Err(UrlToUriError::InvalidHost);
}
let scheme = url.scheme();
let authority = url.authority();
let authority_end = scheme.len() + "://".len() + authority.len();
let path_and_query = &url.as_str()[authority_end..];
Uri::builder()
.scheme(scheme)
.authority(authority)
.path_and_query(path_and_query)
.build()
.map_err(UrlToUriError::Http)
}