Skip to main content

rama_http_hyperium/into_hyperium/
leaf.rs

1//! Leaf-type conversions (method, status, version, uri, header map).
2
3use rama_http_types::{HeaderMap, Method, StatusCode, Version};
4use rama_net::uri::Uri;
5
6use super::TryIntoHyperiumHttp;
7
8impl TryIntoHyperiumHttp for Method {
9    type Output = http::Method;
10    type Error = http::Error;
11
12    fn try_into_hyperium_http(self) -> Result<http::Method, http::Error> {
13        // Both are byte-identical forks; round-trip through the method bytes.
14        Ok(http::Method::from_bytes(self.as_str().as_bytes())?)
15    }
16}
17
18impl TryIntoHyperiumHttp for StatusCode {
19    type Output = http::StatusCode;
20    type Error = http::Error;
21
22    fn try_into_hyperium_http(self) -> Result<http::StatusCode, http::Error> {
23        Ok(http::StatusCode::from_u16(self.as_u16())?)
24    }
25}
26
27impl TryIntoHyperiumHttp for Version {
28    type Output = http::Version;
29    type Error = http::Error;
30
31    fn try_into_hyperium_http(self) -> Result<http::Version, http::Error> {
32        // Total: rama and hyperium expose the same five versions.
33        Ok(match self {
34            Self::HTTP_09 => http::Version::HTTP_09,
35            Self::HTTP_10 => http::Version::HTTP_10,
36            Self::HTTP_11 => http::Version::HTTP_11,
37            Self::HTTP_2 => http::Version::HTTP_2,
38            Self::HTTP_3 => http::Version::HTTP_3,
39        })
40    }
41}
42
43impl TryIntoHyperiumHttp for Uri {
44    type Output = http::Uri;
45    type Error = http::Error;
46
47    fn try_into_hyperium_http(self) -> Result<http::Uri, http::Error> {
48        // The HTTP asterisk-form has no `http::Uri` representation beyond `*`.
49        if self.is_asterisk() {
50            return Ok(http::Uri::from_static("*"));
51        }
52        Ok(http::Uri::try_from(self.as_str().as_ref())?)
53    }
54}
55
56impl TryIntoHyperiumHttp for HeaderMap {
57    type Output = http::HeaderMap;
58    type Error = http::Error;
59
60    fn try_into_hyperium_http(self) -> Result<http::HeaderMap, http::Error> {
61        // Both are byte-identical forks; round-trip each name/value through its
62        // bytes, preserving multi-value ordering and the sensitivity flag.
63        let mut out = http::HeaderMap::with_capacity(self.len());
64        let mut last: Option<http::header::HeaderName> = None;
65        for (name, hv) in self {
66            let mut out_hv = http::header::HeaderValue::from_bytes(hv.as_bytes())?;
67            out_hv.set_sensitive(hv.is_sensitive());
68            match name {
69                Some(name) => {
70                    let name = http::header::HeaderName::from_bytes(name.as_str().as_bytes())?;
71                    out.append(name.clone(), out_hv);
72                    last = Some(name);
73                }
74                // `None` name repeats the previous name (multi-value).
75                None => {
76                    if let Some(name) = &last {
77                        out.append(name.clone(), out_hv);
78                    }
79                }
80            }
81        }
82        Ok(out)
83    }
84}