use std::{fmt, str::FromStr};
use http::{Uri, uri::PathAndQuery};
use crate::{
common::{Error, Result},
error::ConnectionError,
};
#[derive(Clone, Hash, PartialEq, Eq, Default)]
pub struct Address {
uri: Uri,
}
impl Address {
const DEFAULT_PATH: &'static str = "/";
pub(crate) fn into_uri(self) -> Uri {
self.uri
}
pub(crate) fn uri_scheme(&self) -> Option<&http::uri::Scheme> {
self.uri.scheme()
}
pub(crate) fn with_scheme(&self, scheme: http::uri::Scheme) -> Self {
let mut parts = self.uri.clone().into_parts();
parts.scheme = Some(scheme);
if parts.path_and_query.is_none() {
parts.path_and_query = Some(PathAndQuery::from_static(Self::DEFAULT_PATH));
}
Self { uri: Uri::from_parts(parts).expect("Expected valid URI after scheme change") }
}
}
impl FromStr for Address {
type Err = Error;
fn from_str(address: &str) -> Result<Self> {
let uri = address.parse::<Uri>()?;
if uri.port().is_none() {
return Err(Error::Connection(ConnectionError::MissingPort { address: address.to_owned() }));
}
Ok(Self { uri })
}
}
impl fmt::Display for Address {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.uri.authority().unwrap())
}
}
impl fmt::Debug for Address {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.uri)
}
}