Skip to main content

rama_http_headers/common/
location.rs

1use rama_core::error::{BoxError, ErrorContext as _};
2use rama_http_types::{HeaderValue, header::ToStrError};
3use rama_net::uri::Uri;
4
5/// `Location` header, defined in
6/// [RFC7231](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.2)
7///
8/// The `Location` header field is used in some responses to refer to a
9/// specific resource in relation to the response.  The type of
10/// relationship is defined by the combination of request method and
11/// status code semantics.
12///
13/// # ABNF
14///
15/// ```text
16/// Location = URI-reference
17/// ```
18///
19/// # Example values
20/// * `/People.html#tim`
21/// * `http://www.example.net/index.html`
22///
23/// # Examples
24///
25#[derive(Clone, Debug, PartialEq)]
26pub struct Location(HeaderValue);
27
28derive_header! {
29    Location(_),
30    name: LOCATION
31}
32
33impl Location {
34    pub fn new(value: HeaderValue) -> Self {
35        Self(value)
36    }
37
38    pub fn to_str(&self) -> Result<&str, ToStrError> {
39        self.0.to_str()
40    }
41}
42
43impl TryFrom<Uri> for Location {
44    type Error = BoxError;
45
46    #[inline]
47    fn try_from(value: Uri) -> Result<Self, Self::Error> {
48        Self::try_from(&value)
49    }
50}
51
52impl TryFrom<&Uri> for Location {
53    type Error = BoxError;
54
55    fn try_from(value: &Uri) -> Result<Self, Self::Error> {
56        Ok(Self(
57            HeaderValue::try_from(value.to_string()).context("parse uri as header value")?,
58        ))
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::super::test_decode;
65    use super::*;
66
67    #[test]
68    fn absolute_uri() {
69        let s = "http://www.example.net/index.html";
70        let loc = test_decode::<Location>(&[s]).unwrap();
71
72        assert_eq!(loc, Location(HeaderValue::from_static(s)));
73    }
74
75    #[test]
76    fn relative_uri_with_fragment() {
77        let s = "/People.html#tim";
78        let loc = test_decode::<Location>(&[s]).unwrap();
79
80        assert_eq!(loc, Location(HeaderValue::from_static(s)));
81    }
82}