diff --git a/src/common/location.rs b/src/common/location.rs index 54a1cc51..51d6afd3 100644 --- a/src/common/location.rs +++ b/src/common/location.rs @@ -1,3 +1,6 @@ +use std::convert::TryFrom; + +use http::Uri; use HeaderValue; /// `Location` header, defined in @@ -28,6 +31,23 @@ derive_header! { name: LOCATION } +impl Location { + /// Accesses the header's value + pub fn value(&self) -> &HeaderValue { + &self.0 + } +} + +impl From for Location { + fn from(uri: Uri) -> Self { + Self( + HeaderValue::try_from(uri.to_string()) + // cf. https://www.rfc-editor.org/rfc/rfc3986#section-2 + .expect("All URI characters should be valid HTTP header value characters"), + ) + } +} + #[cfg(test)] mod tests { use super::super::test_decode; @@ -48,4 +68,21 @@ mod tests { assert_eq!(loc, Location(HeaderValue::from_static(s))); } + + #[test] + fn uri_constructor() { + let s = "https://www.rust-lang.org/tools"; + let uri: Uri = s.parse().unwrap(); + let loc = Location::from(uri); + + assert_eq!(loc, Location(HeaderValue::from_static(s))); + assert_eq!(loc.value().to_str().unwrap(), s); + } + + #[test] + fn uri_constructor_invalid_chars() { + let s = "https://www.rust-lang.org/hélas"; + let uri: Result = s.parse(); + assert!(uri.is_err()); + } }