uri-url 0.3.0

Efficient Conversion of URIs and URLs
Documentation
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

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)
}