diff --git a/src/format.rs b/src/format.rs index e85e4d8c5..139ca02ca 100644 --- a/src/format.rs +++ b/src/format.rs @@ -144,4 +144,23 @@ mod tests { assert_eq!(url.to_string(), result.to_string()); } } + + #[test] + fn authorities() { + let data = [ + ("http://example.com/", "example.com"), + ("http://noslash.com", "noslash.com"), + ("http://@emptyuser.com/", "emptyuser.com"), + ("http://:@emptypass.com/", ":@emptypass.com"), + ("http://user@user.com/", "user@user.com"), + ("http://user:pass@userpass.com/", "user:pass@userpass.com"), + ("http://host.com:8080/path", "host.com:8080"), + ("http://user:pass@host.com:8080/path", "user:pass@host.com:8080"), + ]; + for &(input, result) in data.iter() { + let url = Url::parse(input).unwrap(); + let auth = url.authority().unwrap(); + assert_eq!(auth.to_string(), result.to_string()); + } + } } diff --git a/src/lib.rs b/src/lib.rs index 779b85589..7b2e67f9e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -247,6 +247,40 @@ pub struct RelativeSchemeData { pub path: Vec, } +/// The Authority part of a URI. +pub struct Authority<'a> { + username: Option<&'a str>, + password: Option<&'a str>, + host: Option<&'a Host>, + port: Option +} + +impl<'a> Show for Authority<'a> { + fn fmt(&self, fmt: &mut Formatter) -> Result<(), FormatError> { + match self.username { + Some(ref u) => { + try!(UserInfoFormatter { + username: *u, + password: self.password + }.fmt(fmt)); + }, + None => () + } + match self.host { + Some(ref h) => try!(h.fmt(fmt)), + None => () + } + match self.port { + Some(ref p) => { + try!(':'.fmt(fmt)); + try!(p.fmt(fmt)); + }, + None => () + } + Ok(()) + } +} + impl hash::Hash for Url { fn hash(&self, state: &mut S) { self.serialize().hash(state) @@ -554,6 +588,17 @@ impl Url { } } + /// If the URL is in a *relative scheme*, return its Authority. + #[inline] + pub fn authority<'a>(&'a self) -> Option> { + self.relative_scheme_data().and(Some(Authority { + username: self.username(), + password: self.password(), + host: self.host(), + port: self.port() + })) + } + /// If the URL is in a *relative scheme*, return its username. #[inline] pub fn username<'a>(&'a self) -> Option<&'a str> {