tcplane/context/impl.rs
1use crate::*;
2
3/// Manages the internal state of the context.
4impl InnerContext {
5 /// Creates a new `InnerContext` with default values.
6 ///
7 /// # Returns
8 ///
9 /// - `InnerContext` - A new instance of `InnerContext`.
10 pub fn new() -> Self {
11 InnerContext {
12 stream: None,
13 request: Request::new(),
14 response: Response::default(),
15 data: HashMap::default(),
16 }
17 }
18}
19
20/// Provides thread-safe access and manipulation of the context.
21impl Context {
22 /// Creates a `Context` from an `InnerContext`.
23 ///
24 /// # Arguments
25 ///
26 /// - `InnerContext` - The inner context to wrap.
27 ///
28 /// # Returns
29 ///
30 /// - `Self` - A new `Context` instance.
31 pub(crate) fn from_inner_context(ctx: InnerContext) -> Self {
32 Self(Arc::new(RwLock::new(ctx)))
33 }
34
35 /// Gets a read lock for the inner context.
36 ///
37 /// # Arguments
38 ///
39 /// - `&self` - A reference to the `Context`.
40 ///
41 /// # Returns
42 ///
43 /// - `RwLockReadContext` - A read guard for the inner context.
44 pub async fn get_read_lock(&self) -> RwLockReadContext {
45 self.0.read().await
46 }
47
48 /// Gets a write lock for the inner context.
49 ///
50 /// # Arguments
51 ///
52 /// - `&self` - A reference to the `Context`.
53 ///
54 /// # Returns
55 ///
56 /// - `RwLockWriteContext` - A write guard for the inner context.
57 pub async fn get_write_lock(&self) -> RwLockWriteContext {
58 self.0.write().await
59 }
60
61 /// Gets a clone of the inner context.
62 ///
63 /// # Arguments
64 ///
65 /// - `&self` - A reference to the `Context`.
66 ///
67 /// # Returns
68 ///
69 /// - `InnerContext` - A cloned inner context.
70 pub async fn get(&self) -> InnerContext {
71 self.get_read_lock().await.clone()
72 }
73
74 /// Gets the stream from the inner context.
75 ///
76 /// # Arguments
77 ///
78 /// - `&self` - A reference to the `Context`.
79 ///
80 /// # Returns
81 ///
82 /// - `OptionArcRwLockStream` - The optional stream.
83 pub async fn get_stream(&self) -> OptionArcRwLockStream {
84 self.get().await.stream.clone()
85 }
86
87 /// Gets the request from the inner context.
88 ///
89 /// # Arguments
90 ///
91 /// - `&self` - A reference to the `Context`.
92 ///
93 /// # Returns
94 ///
95 /// - `Request` - The request object.
96 pub async fn get_request(&self) -> Request {
97 self.get().await.request.clone()
98 }
99
100 /// Gets the response from the inner context.
101 ///
102 /// # Arguments
103 ///
104 /// - `&self` - A reference to the `Context`.
105 ///
106 /// # Returns
107 ///
108 /// - `Response` - The response object.
109 pub async fn get_response(&self) -> Response {
110 self.get().await.response.clone()
111 }
112
113 /// Sets response data.
114 ///
115 /// # Arguments
116 ///
117 /// - `&self` - A reference to the `Context`.
118 /// - `data` - The data to set, which can be converted into `ResponseData`.
119 ///
120 /// # Returns
121 ///
122 /// - `&Self` - A reference to the `Context`.
123 pub(super) async fn set_response_data<T: Into<ResponseData>>(&self, data: T) -> &Self {
124 self.get_write_lock().await.response.set_response_data(data);
125 self
126 }
127
128 /// Gets the socket address from the stream.
129 ///
130 /// # Arguments
131 ///
132 /// - `&self` - A reference to the `Context`.
133 ///
134 /// # Returns
135 ///
136 /// - `OptionSocketAddr` - The optional socket address.
137 pub async fn get_socket_addr(&self) -> OptionSocketAddr {
138 let stream_result: OptionArcRwLockStream = self.get_stream().await;
139 if stream_result.is_none() {
140 return None;
141 }
142 let socket_addr_opt: OptionSocketAddr = stream_result
143 .unwrap()
144 .get_read_lock()
145 .await
146 .peer_addr()
147 .ok();
148 socket_addr_opt
149 }
150
151 /// Gets the socket address or a default if none is available.
152 ///
153 /// # Arguments
154 ///
155 /// - `&self` - A reference to the `Context`.
156 ///
157 /// # Returns
158 ///
159 /// - `SocketAddr` - The socket address or the default socket address.
160 pub async fn get_socket_addr_or_default(&self) -> SocketAddr {
161 let stream_result: OptionArcRwLockStream = self.get_stream().await;
162 if stream_result.is_none() {
163 return DEFAULT_SOCKET_ADDR;
164 }
165 let socket_addr: SocketAddr = stream_result
166 .unwrap()
167 .get_read_lock()
168 .await
169 .peer_addr()
170 .unwrap_or(DEFAULT_SOCKET_ADDR);
171 socket_addr
172 }
173
174 /// Gets the socket address as a string.
175 ///
176 /// # Arguments
177 ///
178 /// - `&self` - A reference to the `Context`.
179 ///
180 /// # Returns
181 ///
182 /// - `Option<String>` - The socket address as a string, if available.
183 pub async fn get_socket_addr_string(&self) -> Option<String> {
184 self.get_socket_addr().await.map(|data| data.to_string())
185 }
186
187 /// Gets the socket address as a string, or a default string if none is available.
188 ///
189 /// # Arguments
190 ///
191 /// - `&self` - A reference to the `Context`.
192 ///
193 /// # Returns
194 ///
195 /// - `String` - The socket address as a string, or the default socket address string.
196 pub async fn get_socket_addr_or_default_string(&self) -> String {
197 self.get_socket_addr_or_default().await.to_string()
198 }
199
200 /// Gets the socket host from the socket address.
201 ///
202 /// # Arguments
203 ///
204 /// - `&self` - A reference to the `Context`.
205 ///
206 /// # Returns
207 ///
208 /// - `OptionSocketHost` - The optional socket host.
209 pub async fn get_socket_host(&self) -> OptionSocketHost {
210 self.get_socket_addr()
211 .await
212 .map(|socket_addr: SocketAddr| socket_addr.ip())
213 }
214
215 /// Gets the socket port from the socket address.
216 ///
217 /// # Arguments
218 ///
219 /// - `&self` - A reference to the `Context`.
220 ///
221 /// # Returns
222 ///
223 /// - `OptionSocketPort` - The optional socket port.
224 pub async fn get_socket_port(&self) -> OptionSocketPort {
225 self.get_socket_addr()
226 .await
227 .map(|socket_addr: SocketAddr| socket_addr.port())
228 }
229
230 /// Sends data through the stream.
231 ///
232 /// # Arguments
233 ///
234 /// - `&self` - A reference to the `Context`.
235 /// - `data` - The data to send, which can be converted into `ResponseData`.
236 ///
237 /// # Returns
238 ///
239 /// - `ResponseResult` - Ok(()) on success, or an error if the stream is not found or sending fails.
240 pub async fn send<T: Into<ResponseData>>(&self, data: T) -> ResponseResult {
241 if let Some(stream) = self.get_stream().await {
242 self.set_response_data(data)
243 .await
244 .get_response()
245 .await
246 .send(&stream)
247 .await?;
248 return Ok(());
249 }
250 Err(ResponseError::NotFoundStream)
251 }
252
253 /// Closes the stream.
254 ///
255 /// # Arguments
256 ///
257 /// - `&self` - A reference to the `Context`.
258 ///
259 /// # Returns
260 ///
261 /// - `ResponseResult` - Ok(()) on success, or an error if the stream is not found or closing fails.
262 pub async fn close(&self) -> ResponseResult {
263 if let Some(stream) = self.get_stream().await {
264 self.get_response().await.close(&stream).await?;
265 return Ok(());
266 }
267 Err(ResponseError::NotFoundStream)
268 }
269
270 /// Flushes the stream.
271 ///
272 /// # Arguments
273 ///
274 /// - `&self` - A reference to the `Context`.
275 ///
276 /// # Returns
277 ///
278 /// - `ResponseResult` - Ok(()) on success, or an error if the stream is not found or flushing fails.
279 pub async fn flush(&self) -> ResponseResult {
280 if let Some(stream) = self.get_stream().await {
281 self.get_response().await.flush(&stream).await?;
282 return Ok(());
283 }
284 Err(ResponseError::NotFoundStream)
285 }
286
287 /// Sets a data value in the context's data map.
288 ///
289 /// # Arguments
290 ///
291 /// - `&self` - A reference to the `Context`.
292 /// - `key` - The key for the data.
293 /// - `value` - The value to set, which must be cloneable and thread-safe.
294 ///
295 /// # Returns
296 ///
297 /// - `&Self` - A reference to the `Context`.
298 pub async fn set_data_value<T: Any + Send + Sync + Clone>(
299 &self,
300 key: &str,
301 value: &T,
302 ) -> &Self {
303 self.get_write_lock()
304 .await
305 .data
306 .insert(key.to_owned(), Arc::new(value.clone()));
307 self
308 }
309
310 /// Gets a data value from the context's data map.
311 ///
312 /// # Arguments
313 ///
314 /// - `&self` - A reference to the `Context`.
315 /// - `key` - The key for the data.
316 ///
317 /// # Returns
318 ///
319 /// - `Option<T>` - The data value if found and successfully downcasted, otherwise `None`.
320 pub async fn get_data_value<T: Any + Send + Sync + Clone>(&self, key: &str) -> Option<T> {
321 self.get_read_lock()
322 .await
323 .data
324 .get(key)
325 .and_then(|arc| arc.downcast_ref::<T>())
326 .cloned()
327 }
328
329 /// Removes a data value from the context's data map.
330 ///
331 /// # Arguments
332 ///
333 /// - `&self` - A reference to the `Context`.
334 /// - `key` - The key of the data to remove.
335 ///
336 /// # Returns
337 ///
338 /// - `&Self` - A reference to the `Context`.
339 pub async fn remove_data_value(&self, key: &str) -> &Self {
340 self.get_write_lock().await.data.remove(key);
341 self
342 }
343
344 /// Clears all data from the context's data map.
345 ///
346 /// # Arguments
347 ///
348 /// - `&self` - A reference to the `Context`.
349 ///
350 /// # Returns
351 ///
352 /// - `&Self` - A reference to the `Context`.
353 pub async fn clear_data(&self) -> &Self {
354 self.get_write_lock().await.data.clear();
355 self
356 }
357}