use crate::*;
use std::fmt;
pub(crate) struct UriRefDisplay<'a> {
scheme: Option<&'a Scheme>,
authority: Option<&'a Authority>,
resource: &'a Resource,
}
impl fmt::Display for UriRefDisplay<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let uri = self;
if let Some(s) = &uri.scheme {
write!(f, "{}:", s.as_str())?;
}
if let Some(authority) = &uri.authority {
f.write_str("//")?;
if let Some(user_info) = &authority.user_info {
write!(f, "{}@", user_info.as_str())?;
}
write!(f, "{}", &authority.host)?;
if let Some(port) = &authority.port {
write!(f, ":{}", port)?;
}
}
f.write_str(uri.resource.path.as_str())?;
if let Some(query) = &uri.resource.query {
write!(f, "?{}", query.as_str())?;
}
if let Some(fragment) = &uri.resource.fragment {
write!(f, "#{}", fragment.as_str())?;
}
Ok(())
}
}
impl<'a> From<&'a Uri> for UriRefDisplay<'a> {
fn from(uri: &'a Uri) -> Self {
Self {
scheme: Some(&uri.scheme),
authority: uri.authority.as_ref(),
resource: &uri.resource,
}
}
}
impl<'a> From<&'a UriRef> for UriRefDisplay<'a> {
fn from(uri: &'a UriRef) -> Self {
Self {
scheme: uri.scheme.as_ref(),
authority: uri.authority.as_ref(),
resource: &uri.resource,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use shared_bytes::SharedStr;
#[test]
fn parse_is_inverse_of_display() {
test_parse_is_inverse_of_display(
"https://ferris@www.example.com/my/resource?search=rust#headline".into(),
);
}
fn test_parse_is_inverse_of_display(input: SharedStr) {
let uri = UriRef::parse(input.clone()).unwrap();
assert_eq!(input, UriRefDisplay::from(&uri).to_string());
}
}