1use http_data::{
2 Connection, DataKind, DataKinds, HeaderData, Headers, Method, MethodData, RequestDataProvider,
3};
4
5use std::{
6 collections::HashMap,
7 net::{IpAddr, Ipv6Addr, SocketAddr},
8};
9
10pub struct ReqWrap<'m> {
11 client: SocketAddr,
12 server: SocketAddr,
13 method: &'m str,
14 headers: HashMap<String, String>,
15 body: String,
16}
17impl ReqWrap<'_> {
18 pub fn set_header(&mut self, name: &str, value: &str) {
19 self.headers.insert(name.to_string(), value.to_string());
20 }
21}
22
23impl Default for ReqWrap<'_> {
24 fn default() -> Self {
25 let local = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 3000);
26 ReqWrap {
27 client: local,
28 server: local,
29 method: "GET",
30 headers: HashMap::new(),
31 body: String::new(),
32 }
33 }
34}
35impl Connection<SocketAddr> for &ReqWrap<'_> {
36 fn client_socket(&self) -> Self::Target<'_> {
37 self.client
38 }
39 fn server_socket(&self) -> Self::Target<'_> {
40 self.server
41 }
42 fn tls_version(&self) -> Option<http_data::TlsVersion> {
43 Some(http_data::TlsVersion::Unknown(0))
44 }
45
46 type Target<'a>
47 = SocketAddr
48 where
49 Self: 'a;
50}
51
52impl RequestDataProvider for ReqWrap<'_> {
53 fn body(&self) -> Option<impl http_body::Body> {
54 Some(http_body_util::Full::new(self.body.as_bytes()))
55 }
56 fn http_version(&self) -> Option<http_data::HttpVersion> {
57 todo!()
58 }
59 fn time_received(&self) -> Option<std::time::SystemTime> {
60 todo!()
61 }
62
63 const URI_KINDS: DataKinds = DataKinds::from_slice(&[DataKind::Str, DataKind::Bytes]);
64 const HEADER_KINDS: DataKinds = DataKinds::from_slice(&[DataKind::Str, DataKind::Bytes]);
65 const METHOD_KINDS: DataKinds = DataKinds::from_slice(&[DataKind::Str, DataKind::Bytes]);
66
67 fn provide_method(&self, dk: DataKind) -> Option<MethodData<'_>> {
68 match dk {
69 DataKind::Str => {
70 let m = Method::<str>::method(self);
71 Some(MethodData::Str(m))
72 }
73 DataKind::Bytes => Some(MethodData::Bytes(self.method.as_bytes())),
74 _ => None,
75 }
76 }
77 fn provide_headers(&self, dk: DataKind) -> Option<HeaderData<'_>> {
78 match dk {
79 DataKind::Str => {
80 let iter = self.headers();
82 Some(HeaderData::Str(Box::new(iter)))
83 }
84 DataKind::Bytes => {
85 let iter = self
86 .headers
87 .iter()
88 .map(|(k, v)| (k.as_bytes(), v.as_bytes()));
89 Some(HeaderData::Bytes(Box::new(iter)))
90 }
91 _ => None,
92 }
93 }
94
95 fn provide_uri(&self, _dk: DataKind) -> Option<http_data::UriData<'_>> {
96 todo!()
97 }
98}
99impl Headers<str, str> for ReqWrap<'_> {
100 type N<'n>
101 = &'n str
102 where
103 Self: 'n;
104
105 type V<'n>
106 = &'n str
107 where
108 Self: 'n;
109 fn headers(&self) -> impl Iterator<Item = (Self::N<'_>, Self::V<'_>)> {
110 self.headers.iter().map(|(k, v)| (k.as_ref(), v.as_ref()))
111 }
112}
113
114impl Method<str> for ReqWrap<'_> {
126 type Target<'a>
127 = &'a str
128 where
129 Self: 'a;
130 fn method(&self) -> Self::Target<'_> {
131 self.method
132 }
133}
134impl Method<[u8]> for ReqWrap<'_> {
135 type Target<'a>
136 = &'a [u8]
137 where
138 Self: 'a;
139 fn method(&self) -> Self::Target<'_> {
140 self.method.as_bytes()
141 }
142}
143
144fn main() {
145 use http_data::{DataKind, HeaderData, MethodData, RequestDataProvider as _};
146
147 let mut req = ReqWrap::default();
148 req.set_header("Content-Type", "application/json");
149
150 let method = http_data::Method::<str>::method(&req);
151 dbg!(method);
152
153 let method = if let Some(MethodData::Str(m)) = req.provide_method(DataKind::Str) {
154 m.to_string()
155 } else if let Some(MethodData::Bytes(m)) = req.provide_method(DataKind::Bytes) {
156 let v = m.to_vec();
157 String::from_utf8(v).unwrap()
158 } else {
159 panic!("Unsupported method");
160 };
161
162 dbg!(method);
163 let mut headers: Vec<(String, String)> = vec![];
164 match req.provide_headers(DataKind::Str) {
165 Some(HeaderData::Str(hs)) => {
166 for (name, value) in hs {
167 headers.push((name.to_string(), value.to_string()));
168 }
169 }
170 _ => match req.provide_headers(DataKind::Bytes) {
171 Some(HeaderData::Bytes(hs)) => {
172 for (name, value) in hs {
173 let name = String::from_utf8_lossy(name).to_string();
174 let value = String::from_utf8_lossy(value).to_string();
175 headers.push((name, value));
176 }
177 }
178 _ => {
179 panic!("Unsupported headers");
180 }
181 },
182 }
183
184 dbg!(headers);
185}