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}