rama_http_hyperium/
lib.rs1#![doc(
34 html_favicon_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/rama_logo.svg"
35)]
36#![doc(
37 html_logo_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/rama_logo.svg"
38)]
39#![cfg_attr(docsrs, feature(doc_cfg))]
40
41use rama_core::extensions::Extension;
42use rama_http_types::{
43 HeaderMap, Method, Request, Response, StatusCode, Version, request, response,
44};
45use rama_net::uri::Uri;
46
47mod into_hyperium;
48mod into_rama;
49
50#[doc(inline)]
51pub use into_hyperium::{HyperiumBody, HyperiumBodyError, TryIntoHyperiumHttp};
52#[doc(inline)]
53pub use into_rama::{RamaBody, RamaBodyError, TryIntoRamaHttp};
54
55mod sealed {
56 pub trait Sealed {}
59}
60
61macro_rules! impl_sealed {
62 ($($ty:ty),* $(,)?) => {
63 $( impl crate::sealed::Sealed for $ty {} )*
64 };
65}
66
67impl_sealed!(
68 Method,
69 StatusCode,
70 Version,
71 Uri,
72 HeaderMap,
73 request::Parts,
74 response::Parts,
75 http::Method,
76 http::StatusCode,
77 http::Version,
78 http::Uri,
79 http::HeaderMap,
80 http::request::Parts,
81 http::response::Parts,
82);
83impl<T> sealed::Sealed for Request<T> {}
84impl<T> sealed::Sealed for Response<T> {}
85impl<T> sealed::Sealed for http::Request<T> {}
86impl<T> sealed::Sealed for http::Response<T> {}
87impl sealed::Sealed for &http::HeaderMap {}
88
89#[derive(Clone, Debug, Extension)]
92pub(crate) struct HyperExtensions(pub(crate) http::Extensions);
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn request_round_trip() {
100 let hyper = http::Request::builder()
101 .method("POST")
102 .uri("https://example.com:8443/path?q=1")
103 .header("x-test", "v")
104 .body(())
105 .unwrap();
106 let rama: Request<()> = hyper.try_into_rama_http().unwrap();
107 assert_eq!(rama.method().as_str(), "POST");
108 assert_eq!(rama.uri().to_string(), "https://example.com:8443/path?q=1");
109 assert_eq!(rama.headers().get("x-test").unwrap().as_bytes(), b"v");
110
111 let back: http::Request<()> = rama.try_into_hyperium_http().unwrap();
112 assert_eq!(back.method(), "POST");
113 assert_eq!(back.uri(), "https://example.com:8443/path?q=1");
114 assert_eq!(back.headers().get("x-test").unwrap(), "v");
115 }
116
117 #[test]
118 fn request_round_trip_preserves_rama_extension() {
119 use rama_core::extensions::ExtensionsRef as _;
120
121 #[derive(Debug, Clone, PartialEq, Eq, Extension)]
122 struct Label(u32);
123
124 let rama = Request::builder().uri("http://x/").body(()).unwrap();
125 rama.extensions().insert(Label(7));
126
127 let hyper: http::Request<()> = rama.try_into_hyperium_http().unwrap();
129 let back: Request<()> = hyper.try_into_rama_http().unwrap();
130 assert_eq!(*back.extensions().get_ref::<Label>().unwrap(), Label(7));
131 }
132
133 #[test]
134 fn response_round_trip() {
135 let hyper = http::Response::builder()
136 .status(404)
137 .header("x-y", "z")
138 .body(())
139 .unwrap();
140 let rama: Response<()> = hyper.try_into_rama_http().unwrap();
141 assert_eq!(rama.status().as_u16(), 404);
142
143 let back: http::Response<()> = rama.try_into_hyperium_http().unwrap();
144 assert_eq!(back.status(), 404);
145 assert_eq!(back.headers().get("x-y").unwrap(), "z");
146 }
147
148 #[test]
149 fn http_uri_authority_form_preserves_host() {
150 let mut parts = http::uri::Parts::default();
153 parts.authority = Some("example.com:443".parse().unwrap());
154 let hyper_uri = http::Uri::from_parts(parts).unwrap();
155 assert!(hyper_uri.scheme().is_none() && hyper_uri.authority().is_some());
156
157 let rama_uri: Uri = hyper_uri.try_into_rama_http().unwrap();
158 assert_eq!(
159 rama_uri.host(),
160 Some(rama_net::address::Host::EXAMPLE_NAME.view())
161 );
162 assert_eq!(rama_uri.port_u16(), Some(443));
163 }
164}