xitca_http/h1/proto/
context.rs1use core::{mem, net::SocketAddr};
2
3use crate::http::{Extensions, header::HeaderMap};
4
5pub struct Context<'a, D, const HEADER_LIMIT: usize> {
7 addr: SocketAddr,
8 state: ContextState,
9 header: Option<HeaderMap>,
11 exts: Extensions,
13 date: &'a D,
14}
15
16struct ContextState(u8);
19
20impl ContextState {
21 const EXPECT: u8 = 0b_0001;
23 const CONNECT: u8 = 0b_0010;
25 const HEAD: u8 = 0b_0100;
27 const CLOSE: u8 = 0b_1000;
29
30 const fn new() -> Self {
31 Self(0)
32 }
33
34 fn insert(&mut self, other: u8) {
35 self.0 |= other;
36 }
37
38 fn remove(&mut self, other: u8) {
39 self.0 &= !other;
40 }
41
42 const fn contains(&self, other: u8) -> bool {
43 (self.0 & other) == other
44 }
45}
46
47impl<'a, D, const HEADER_LIMIT: usize> Context<'a, D, HEADER_LIMIT> {
48 #[inline]
52 pub fn new(date: &'a D) -> Self {
53 Self::with_addr(crate::unspecified_socket_addr(), date)
54 }
55
56 #[inline]
60 pub fn with_addr(addr: SocketAddr, date: &'a D) -> Self {
61 Self {
62 addr,
63 state: ContextState::new(),
64 header: None,
65 exts: Extensions::new(),
66 date,
67 }
68 }
69
70 #[inline]
72 pub fn date(&self) -> &D {
73 self.date
74 }
75
76 #[inline]
80 pub fn take_headers(&mut self) -> HeaderMap {
81 self.header.take().unwrap_or_default()
82 }
83
84 #[inline]
86 pub fn take_extensions(&mut self) -> Extensions {
87 mem::take(&mut self.exts)
88 }
89
90 #[inline]
92 pub fn replace_headers(&mut self, headers: HeaderMap) {
93 debug_assert!(headers.is_empty());
94 self.header = Some(headers);
95 }
96
97 #[inline]
99 pub fn replace_extensions(&mut self, extensions: Extensions) {
100 debug_assert!(extensions.is_empty());
101 self.exts = extensions;
102 }
103
104 #[inline]
106 pub fn reset(&mut self) {
107 self.state = ContextState::new();
108 }
109
110 #[inline]
112 pub fn set_expect_header(&mut self) {
113 self.state.insert(ContextState::EXPECT)
114 }
115
116 #[inline]
118 pub fn set_connect_method(&mut self) {
119 self.state.insert(ContextState::CONNECT)
120 }
121
122 #[inline]
124 pub fn set_head_method(&mut self) {
125 self.state.insert(ContextState::HEAD)
126 }
127
128 #[inline]
130 pub fn set_close(&mut self) {
131 self.state.insert(ContextState::CLOSE)
132 }
133
134 #[inline]
136 pub fn remove_close(&mut self) {
137 self.state.remove(ContextState::CLOSE)
138 }
139
140 #[inline]
142 pub const fn is_expect_header(&self) -> bool {
143 self.state.contains(ContextState::EXPECT)
144 }
145
146 #[inline]
148 pub const fn is_connect_method(&self) -> bool {
149 self.state.contains(ContextState::CONNECT)
150 }
151
152 #[inline]
154 pub const fn is_head_method(&self) -> bool {
155 self.state.contains(ContextState::HEAD)
156 }
157
158 #[inline]
160 pub const fn is_connection_closed(&self) -> bool {
161 self.state.contains(ContextState::CLOSE)
162 }
163
164 #[inline]
166 pub fn socket_addr(&self) -> &SocketAddr {
167 &self.addr
168 }
169}