Skip to main content

embedded_svc/
http.rs

1pub mod client;
2pub mod server;
3
4pub mod status {
5    use core::ops::Range;
6
7    pub const INFO: Range<u16> = 100..200;
8    pub const OK: Range<u16> = 200..300;
9    pub const REDIRECT: Range<u16> = 300..400;
10    pub const CLIENT_ERROR: Range<u16> = 400..500;
11    pub const SERVER_ERROR: Range<u16> = 500..600;
12}
13
14#[derive(Copy, Clone, Debug, PartialEq, Eq)]
15#[cfg_attr(feature = "defmt", derive(defmt::Format))]
16#[cfg_attr(feature = "std", derive(Hash))]
17pub enum Method {
18    Delete,
19    Get,
20    Head,
21    Post,
22    Put,
23    Connect,
24    Options,
25    Trace,
26    Copy,
27    Lock,
28    MkCol,
29    Move,
30    Propfind,
31    Proppatch,
32    Search,
33    Unlock,
34    Bind,
35    Rebind,
36    Unbind,
37    Acl,
38    Report,
39    MkActivity,
40    Checkout,
41    Merge,
42    MSearch,
43    Notify,
44    Subscribe,
45    Unsubscribe,
46    Patch,
47    Purge,
48    MkCalendar,
49    Link,
50    Unlink,
51}
52
53pub trait Headers {
54    fn header(&self, name: &str) -> Option<&'_ str>;
55
56    fn content_type(&self) -> Option<&'_ str> {
57        self.header("Content-Type")
58    }
59
60    fn content_len(&self) -> Option<u64> {
61        self.header("Content-Length")
62            .and_then(|v| v.parse::<u64>().ok())
63    }
64
65    fn content_encoding(&self) -> Option<&'_ str> {
66        self.header("Content-Encoding")
67    }
68
69    fn transfer_encoding(&self) -> Option<&'_ str> {
70        self.header("Transfer-Encoding")
71    }
72
73    fn host(&self) -> Option<&'_ str> {
74        self.header("Host")
75    }
76
77    fn connection(&self) -> Option<&'_ str> {
78        self.header("Connection")
79    }
80
81    fn cache_control(&self) -> Option<&'_ str> {
82        self.header("Cache-Control")
83    }
84
85    fn upgrade(&self) -> Option<&'_ str> {
86        self.header("Upgrade")
87    }
88}
89
90impl<H> Headers for &H
91where
92    H: Headers,
93{
94    fn header(&self, name: &str) -> Option<&'_ str> {
95        (*self).header(name)
96    }
97}
98
99impl<H> Headers for &mut H
100where
101    H: Headers,
102{
103    fn header(&self, name: &str) -> Option<&'_ str> {
104        (**self).header(name)
105    }
106}
107
108pub trait Status {
109    fn status(&self) -> u16;
110
111    fn status_message(&self) -> Option<&'_ str>;
112}
113
114impl<S> Status for &S
115where
116    S: Status,
117{
118    fn status(&self) -> u16 {
119        (*self).status()
120    }
121
122    fn status_message(&self) -> Option<&'_ str> {
123        (*self).status_message()
124    }
125}
126
127impl<S> Status for &mut S
128where
129    S: Status,
130{
131    fn status(&self) -> u16 {
132        (**self).status()
133    }
134
135    fn status_message(&self) -> Option<&'_ str> {
136        (**self).status_message()
137    }
138}
139
140pub trait Query {
141    fn uri(&self) -> &'_ str;
142
143    fn method(&self) -> Method;
144}
145
146impl<Q> Query for &Q
147where
148    Q: Query,
149{
150    fn uri(&self) -> &'_ str {
151        (*self).uri()
152    }
153
154    fn method(&self) -> Method {
155        (*self).method()
156    }
157}
158
159impl<Q> Query for &mut Q
160where
161    Q: Query,
162{
163    fn uri(&self) -> &'_ str {
164        (**self).uri()
165    }
166
167    fn method(&self) -> Method {
168        (**self).method()
169    }
170}
171
172pub mod headers {
173    pub type ContentLenParseBuf = heapless::String<20>;
174
175    pub fn content_type(ctype: &str) -> (&str, &str) {
176        ("Content-Type", ctype)
177    }
178
179    pub fn content_len(len: u64, buf: &mut ContentLenParseBuf) -> (&str, &str) {
180        *buf = ContentLenParseBuf::try_from(len).unwrap();
181
182        ("Content-Length", buf.as_str())
183    }
184
185    pub fn content_encoding(encoding: &str) -> (&str, &str) {
186        ("Content-Encoding", encoding)
187    }
188
189    pub fn transfer_encoding(encoding: &str) -> (&str, &str) {
190        ("Transfer-Encoding", encoding)
191    }
192
193    pub fn transfer_encoding_chunked<'a>() -> (&'a str, &'a str) {
194        transfer_encoding("Chunked")
195    }
196
197    pub fn host(host: &str) -> (&str, &str) {
198        ("Host", host)
199    }
200
201    pub fn connection(connection: &str) -> (&str, &str) {
202        ("Connection", connection)
203    }
204
205    pub fn connection_upgrade<'a>() -> (&'a str, &'a str) {
206        connection("Upgrade")
207    }
208
209    pub fn connection_keepalive<'a>() -> (&'a str, &'a str) {
210        connection("Keep-Alive")
211    }
212
213    pub fn connection_close<'a>() -> (&'a str, &'a str) {
214        connection("Close")
215    }
216
217    pub fn cache_control(cache: &str) -> (&str, &str) {
218        ("Cache-Control", cache)
219    }
220
221    pub fn cache_control_no_cache<'a>() -> (&'a str, &'a str) {
222        cache_control("No-Cache")
223    }
224
225    pub fn location(location: &str) -> (&str, &str) {
226        ("Location", location)
227    }
228
229    pub fn upgrade(upgrade: &str) -> (&str, &str) {
230        ("Upgrade", upgrade)
231    }
232
233    pub fn upgrade_websocket<'a>() -> (&'a str, &'a str) {
234        upgrade("websocket")
235    }
236}
237
238pub mod asynch {
239    pub use super::*;
240}