udp/context/impl.rs
1use crate::*;
2
3/// Implementation of InnerContext methods.
4impl Default for InnerContext {
5 #[inline(always)]
6 fn default() -> Self {
7 Self::new()
8 }
9}
10
11impl InnerContext {
12 /// Creates a new InnerContext with default values.
13 ///
14 /// # Returns
15 ///
16 /// - `InnerContext` - New context instance.
17 #[inline(always)]
18 pub fn new() -> Self {
19 InnerContext {
20 socket: None,
21 request: Request::new(),
22 response: Response::default(),
23 socket_addr: None,
24 data: HashMap::default(),
25 }
26 }
27}
28
29/// Implementation of Context methods.
30///
31/// Provides thread-safe operations on the UDP context.
32impl Context {
33 /// Creates a Context from an InnerContext.
34 ///
35 /// # Arguments
36 ///
37 /// - `InnerContext` - The inner context to wrap.
38 ///
39 /// # Returns
40 ///
41 /// - `Context` - New thread-safe context wrapper.
42 pub(crate) fn from_inner_context(ctx: InnerContext) -> Self {
43 Self(Arc::new(RwLock::new(ctx)))
44 }
45
46 /// Acquires a read lock on the inner context.
47 ///
48 /// # Returns
49 ///
50 /// - `RwLockReadContext` - Read guard for the inner context.
51 pub async fn get_read_lock(&'_ self) -> RwLockReadContext<'_> {
52 self.0.read().await
53 }
54
55 /// Acquires a write lock on the inner context.
56 ///
57 /// # Returns
58 ///
59 /// - `RwLockWriteContext` - Write guard for the inner context.
60 pub async fn get_write_lock(&'_ self) -> RwLockWriteContext<'_> {
61 self.0.write().await
62 }
63
64 /// Gets a clone of the inner context.
65 ///
66 /// # Returns
67 ///
68 /// - `InnerContext` - Clone of the inner context.
69 pub async fn get(&self) -> InnerContext {
70 self.get_read_lock().await.clone()
71 }
72
73 /// Gets the request data from the context.
74 ///
75 /// # Returns
76 ///
77 /// - `Request` - Clone of the request data.
78 pub async fn get_request(&self) -> Request {
79 self.get().await.request.clone()
80 }
81
82 /// Gets the response data from the context.
83 ///
84 /// # Returns
85 ///
86 /// - `Response` - Clone of the response data.
87 pub async fn get_response(&self) -> Response {
88 self.get().await.response.clone()
89 }
90
91 /// Gets the UDP socket from the context.
92 ///
93 /// # Returns
94 ///
95 /// - `OptionArcRwLockUdpSocket` - Clone of the socket if present.
96 pub async fn get_socket(&self) -> OptionArcRwLockUdpSocket {
97 self.get().await.socket.clone()
98 }
99
100 /// Gets the socket address from the context.
101 ///
102 /// # Returns
103 ///
104 /// - `OptionSocketAddr` - Clone of the socket address if present.
105 pub async fn get_socket_addr(&self) -> OptionSocketAddr {
106 self.get().await.socket_addr
107 }
108
109 /// Gets the socket address or default if not present.
110 ///
111 /// # Returns
112 ///
113 /// - `SocketAddr` - Socket address or default (0.0.0.0:0).
114 pub async fn get_socket_addr_or_default(&self) -> SocketAddr {
115 let socket_result: OptionArcRwLockUdpSocket = self.get_socket().await;
116 if socket_result.is_none() {
117 return DEFAULT_SOCKET_ADDR;
118 }
119 let socket_addr: SocketAddr = socket_result
120 .unwrap()
121 .get_read_lock()
122 .await
123 .peer_addr()
124 .unwrap_or(DEFAULT_SOCKET_ADDR);
125 socket_addr
126 }
127
128 /// Gets the socket address as a string.
129 ///
130 /// # Returns
131 ///
132 /// - `Option<String>` - Socket address string if present.
133 pub async fn get_socket_addr_string(&self) -> Option<String> {
134 self.get_socket_addr().await.map(|data| data.to_string())
135 }
136
137 /// Gets the socket address or default as a string.
138 ///
139 /// # Returns
140 ///
141 /// - `String` - Socket address string or default.
142 pub async fn get_socket_addr_or_default_string(&self) -> String {
143 self.get_socket_addr_or_default().await.to_string()
144 }
145
146 /// Gets the socket host IP address.
147 ///
148 /// # Returns
149 ///
150 /// - `OptionSocketHost` - Host IP address if present.
151 pub async fn get_socket_host(&self) -> OptionSocketHost {
152 self.get_socket_addr()
153 .await
154 .map(|socket_addr: SocketAddr| socket_addr.ip())
155 }
156
157 /// Gets the socket port number.
158 ///
159 /// # Returns
160 ///
161 /// - `OptionSocketPort` - Port number if present.
162 pub async fn get_socket_port(&self) -> OptionSocketPort {
163 self.get_socket_addr()
164 .await
165 .map(|socket_addr: SocketAddr| socket_addr.port())
166 }
167
168 /// Sets the response data in the context.
169 ///
170 /// # Arguments
171 ///
172 /// - `T` - Data convertible to ResponseData.
173 ///
174 /// # Returns
175 ///
176 /// - `&Self` - Reference to self for chaining.
177 pub(super) async fn set_response<T: Into<ResponseData>>(&self, data: T) -> &Self {
178 self.get_write_lock().await.response = Response::from(data);
179 self
180 }
181
182 /// Sends response data through the socket.
183 ///
184 /// # Arguments
185 ///
186 /// - `T` - Data convertible to ResponseData.
187 ///
188 /// # Returns
189 ///
190 /// - `ResponseResult` - Result of the send operation.
191 pub async fn send<T: Into<ResponseData>>(&self, data: T) -> ResponseResult {
192 let response_result: ResponseResult = self
193 .set_response(data)
194 .await
195 .get_response()
196 .await
197 .send(&self.get_socket().await, &self.get_socket_addr().await)
198 .await;
199 response_result
200 }
201
202 /// Sets a value in the context data storage.
203 ///
204 /// # Arguments
205 ///
206 /// - `&str` - Key for the value.
207 /// - `&T` - Value to store (must be Any + Send + Sync + Clone).
208 ///
209 /// # Returns
210 ///
211 /// - `&Self` - Reference to self for chaining.
212 pub async fn set_data_value<T: Any + Send + Sync + Clone>(
213 &self,
214 key: &str,
215 value: &T,
216 ) -> &Self {
217 self.get_write_lock()
218 .await
219 .data
220 .insert(key.to_owned(), Arc::new(value.clone()));
221 self
222 }
223
224 /// Gets a value from the context data storage.
225 ///
226 /// # Arguments
227 ///
228 /// - `&str` - Key for the value.
229 ///
230 /// # Returns
231 ///
232 /// - `Option<T>` - Retrieved value if present and of correct type.
233 pub async fn get_data_value<T: Any + Send + Sync + Clone>(&self, key: &str) -> Option<T> {
234 self.get_read_lock()
235 .await
236 .data
237 .get(key)
238 .and_then(|arc| arc.downcast_ref::<T>())
239 .cloned()
240 }
241
242 /// Removes a value from the context data storage.
243 ///
244 /// # Arguments
245 ///
246 /// - `&str` - Key for the value to remove.
247 ///
248 /// # Returns
249 ///
250 /// - `&Self` - Reference to self for chaining.
251 pub async fn remove_data_value(&self, key: &str) -> &Self {
252 self.get_write_lock().await.data.remove(key);
253 self
254 }
255
256 /// Clears all data from the context data storage.
257 ///
258 /// # Returns
259 ///
260 /// - `&Self` - Reference to self for chaining.
261 pub async fn clear_data(&self) -> &Self {
262 self.get_write_lock().await.data.clear();
263 self
264 }
265}