1use std::error::Error;
8use std::fmt;
9use std::fmt::{Display, Formatter};
10
11use http::Uri;
12use url::Url;
13
14#[derive(Debug)]
15pub enum UrlToUriError {
16 InvalidAuthority,
17 InvalidHost,
18 Http(http::Error),
19}
20
21impl Display for UrlToUriError {
22 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
23 match self {
24 UrlToUriError::InvalidAuthority => f.write_str("invalid authority"),
25 UrlToUriError::InvalidHost => f.write_str("invalid host"),
26 UrlToUriError::Http(error) => error.fmt(f),
27 }
28 }
29}
30
31impl Error for UrlToUriError {}
32
33pub fn url_to_uri(url: &Url) -> Result<Uri, UrlToUriError> {
34 if !url.has_authority() {
35 return Err(UrlToUriError::InvalidAuthority);
36 }
37 if !url.has_host() {
38 return Err(UrlToUriError::InvalidHost);
39 }
40
41 let scheme = url.scheme();
42 let authority = url.authority();
43
44 let authority_end = scheme.len() + "://".len() + authority.len();
45 let path_and_query = &url.as_str()[authority_end..];
46
47 Uri::builder()
48 .scheme(scheme)
49 .authority(authority)
50 .path_and_query(path_and_query)
51 .build()
52 .map_err(UrlToUriError::Http)
53}