hyperlane_core/context/impl.rs
1use super::*;
2
3/// Implementation of `Default` trait for `Context`.
4impl Default for Context {
5 /// Creates a default `Context` instance.
6 ///
7 /// # Returns
8 ///
9 /// - `Context` - A new context with default values and a static default server.
10 #[inline(always)]
11 fn default() -> Self {
12 Self {
13 request: Request::default(),
14 response: Response::default(),
15 route_params: RouteParams::default(),
16 attributes: ThreadSafeAttributeStore::default(),
17 }
18 }
19}
20
21/// Implementation of `PartialEq` trait for `Context`.
22impl PartialEq for Context {
23 /// Compares two `Context` instances for equality.
24 ///
25 /// # Arguments
26 ///
27 /// - `&Self` - The first `Context` instance.
28 /// - `&Self` - The second `Context` instance.
29 ///
30 /// # Returns
31 ///
32 /// - `bool` - True if the instances are equal, otherwise false.
33 #[inline(always)]
34 fn eq(&self, other: &Self) -> bool {
35 self.get_request() == other.get_request()
36 && self.get_response() == other.get_response()
37 && self.get_route_params() == other.get_route_params()
38 && self.get_attributes().len() == other.get_attributes().len()
39 }
40}
41
42/// Implementation of `Eq` trait for `Context`.
43impl Eq for Context {}
44
45/// Implementation of `From` trait for converting `usize` address into `&Context`.
46impl From<usize> for &'static Context {
47 /// Converts a memory address into a reference to `Context`.
48 ///
49 /// # Arguments
50 ///
51 /// - `usize` - The memory address of the `Context` instance.
52 ///
53 /// # Returns
54 ///
55 /// - `&'static Context` - A reference to the `Context` at the given address.
56 ///
57 /// # Safety
58 ///
59 /// - The address is guaranteed to be a valid `Context` instance
60 /// that was previously converted from a reference and is managed by the runtime.
61 #[inline(always)]
62 fn from(address: usize) -> &'static Context {
63 unsafe { &*(address as *const Context) }
64 }
65}
66
67/// Implementation of `From` trait for converting `usize` address into `&mut Context`.
68impl<'a> From<usize> for &'a mut Context {
69 /// Converts a memory address into a mutable reference to `Context`.
70 ///
71 /// # Arguments
72 ///
73 /// - `usize` - The memory address of the `Context` instance.
74 ///
75 /// # Returns
76 ///
77 /// - `&mut Context` - A mutable reference to the `Context` at the given address.
78 ///
79 /// # Safety
80 ///
81 /// - The address is guaranteed to be a valid `Context` instance
82 /// that was previously converted from a reference and is managed by the runtime.
83 #[inline(always)]
84 fn from(address: usize) -> &'a mut Context {
85 unsafe { &mut *(address as *mut Context) }
86 }
87}
88
89/// Implementation of `From` trait for converting `&Context` into `usize` address.
90impl From<&Context> for usize {
91 /// Converts a reference to `Context` into its memory address.
92 ///
93 /// # Arguments
94 ///
95 /// - `&Context` - The reference to the `Context` instance.
96 ///
97 /// # Returns
98 ///
99 /// - `usize` - The memory address of the `Context` instance.
100 #[inline(always)]
101 fn from(ctx: &Context) -> Self {
102 ctx as *const Context as usize
103 }
104}
105
106/// Implementation of `From` trait for converting `&mut Context` into `usize` address.
107impl From<&mut Context> for usize {
108 /// Converts a mutable reference to `Context` into its memory address.
109 ///
110 /// # Arguments
111 ///
112 /// - `&mut Context` - The mutable reference to the `Context` instance.
113 ///
114 /// # Returns
115 ///
116 /// - `usize` - The memory address of the `Context` instance.
117 #[inline(always)]
118 fn from(ctx: &mut Context) -> Self {
119 ctx as *mut Context as usize
120 }
121}
122
123/// Implementation of `AsRef` trait for `Context`.
124impl AsRef<Context> for Context {
125 /// Converts `&Context` to `&Context` via memory address conversion.
126 ///
127 /// # Returns
128 ///
129 /// - `&Context` - A reference to the `Context` instance.
130 #[inline(always)]
131 fn as_ref(&self) -> &Self {
132 let address: usize = self.into();
133 address.into()
134 }
135}
136
137/// Implementation of `AsMut` trait for `Context`.
138impl AsMut<Context> for Context {
139 /// Converts `&mut Context` to `&mut Context` via memory address conversion.
140 ///
141 /// # Returns
142 ///
143 /// - `&mut Context` - A mutable reference to the `Context` instance.
144 #[inline(always)]
145 fn as_mut(&mut self) -> &mut Self {
146 let address: usize = self.into();
147 address.into()
148 }
149}
150
151/// Implementation of `Lifetime` trait for `Context`.
152impl Lifetime for Context {
153 /// Converts a reference to the context into a `'static` reference.
154 ///
155 /// # Returns
156 ///
157 /// - `&'static Self` - A reference to the context with a `'static` lifetime.
158 ///
159 /// # Safety
160 ///
161 /// - The address is guaranteed to be a valid `Self` instance
162 /// that was previously converted from a reference and is managed by the runtime.
163 #[inline(always)]
164 unsafe fn leak(&self) -> &'static Self {
165 let address: usize = self.into();
166 address.into()
167 }
168
169 /// Converts a reference to the context into a `'static` mutable reference.
170 ///
171 /// # Returns
172 ///
173 /// - `&'static mut Self` - A mutable reference to the context with a `'static` lifetime.
174 ///
175 /// # Safety
176 ///
177 /// - The address is guaranteed to be a valid `Self` instance
178 /// that was previously converted from a reference and is managed by the runtime.
179 #[inline(always)]
180 unsafe fn leak_mut(&self) -> &'static mut Self {
181 let address: usize = self.into();
182 address.into()
183 }
184}
185
186/// Implementation of methods for `Context` structure.
187impl Context {
188 /// Clears all route parameters while retaining the map's allocated capacity.
189 ///
190 /// Used between keep-alive requests on the same connection to avoid
191 /// reallocating the parameter map for every request.
192 ///
193 /// # Returns
194 ///
195 /// - `&mut Self` - A mutable reference to self for chaining.
196 #[inline(always)]
197 pub(crate) fn clear_route_params(&mut self) -> &mut Self {
198 self.get_mut_route_params().clear();
199 self
200 }
201
202 /// Attempts to retrieve a specific route parameter by its name.
203 ///
204 /// # Arguments
205 ///
206 /// - `AsRef<str>` - The name of the route parameter to retrieve.
207 ///
208 /// # Returns
209 ///
210 /// - `Option<String>` - The value of the route parameter if it exists.
211 #[inline(always)]
212 pub fn try_get_route_param<T>(&self, name: T) -> Option<String>
213 where
214 T: AsRef<str>,
215 {
216 self.get_route_params().get(name.as_ref()).cloned()
217 }
218
219 /// Retrieves a specific route parameter by its name, panicking if not found.
220 ///
221 /// # Arguments
222 ///
223 /// - `AsRef<str>` - The name of the route parameter to retrieve.
224 ///
225 /// # Returns
226 ///
227 /// - `String` - The value of the route parameter if it exists.
228 ///
229 /// # Panics
230 ///
231 /// - If the route parameter is not found.
232 #[inline(always)]
233 pub fn get_route_param<T>(&self, name: T) -> String
234 where
235 T: AsRef<str>,
236 {
237 self.try_get_route_param(name).unwrap()
238 }
239
240 /// Attempts to retrieve a specific attribute by its key, casting it to the specified type.
241 ///
242 /// # Arguments
243 ///
244 /// - `AsRef<str>` - The key of the attribute to retrieve.
245 ///
246 /// # Returns
247 ///
248 /// - `Option<V>` - The attribute value if it exists and can be cast to the specified type.
249 #[inline(always)]
250 pub fn try_get_attribute<V>(&self, key: impl AsRef<str>) -> Option<V>
251 where
252 V: AnySendSyncClone,
253 {
254 self.get_attributes()
255 .get(&Attribute::External(key.as_ref().to_owned()).to_string())
256 .and_then(|arc: &ArcAnySendSync| arc.downcast_ref::<V>())
257 .cloned()
258 }
259
260 /// Retrieves a specific attribute by its key, casting it to the specified type, panicking if not found.
261 ///
262 /// # Arguments
263 ///
264 /// - `AsRef<str>` - The key of the attribute to retrieve.
265 ///
266 /// # Returns
267 ///
268 /// - `AnySendSyncClone` - The attribute value if it exists and can be cast to the specified type.
269 ///
270 /// # Panics
271 ///
272 /// - If the attribute is not found.
273 #[inline(always)]
274 pub fn get_attribute<V>(&self, key: impl AsRef<str>) -> V
275 where
276 V: AnySendSyncClone,
277 {
278 self.try_get_attribute(key).unwrap()
279 }
280
281 /// Sets an attribute in the context.
282 ///
283 /// # Arguments
284 ///
285 /// - `AsRef<str>` - The key of the attribute to set.
286 /// - `AnySendSyncClone` - The value of the attribute.
287 ///
288 /// # Returns
289 ///
290 /// - `&mut Self` - A reference to the modified context.
291 #[inline(always)]
292 pub fn set_attribute<K, V>(&mut self, key: K, value: V) -> &mut Self
293 where
294 K: AsRef<str>,
295 V: AnySendSyncClone,
296 {
297 self.get_mut_attributes().insert(
298 Attribute::External(key.as_ref().to_owned()).to_string(),
299 Arc::new(value),
300 );
301 self
302 }
303
304 /// Removes an attribute from the context.
305 ///
306 /// # Arguments
307 ///
308 /// - `AsRef<str>` - The key of the attribute to remove.
309 ///
310 /// # Returns
311 ///
312 /// - `&mut Self` - A reference to the modified context.
313 #[inline(always)]
314 pub fn remove_attribute<K>(&mut self, key: K) -> &mut Self
315 where
316 K: AsRef<str>,
317 {
318 self.get_mut_attributes()
319 .remove(&Attribute::External(key.as_ref().to_owned()).to_string());
320 self
321 }
322
323 /// Clears all attributes from the context.
324 ///
325 /// # Returns
326 ///
327 /// - `&mut Self` - A reference to the modified context.
328 #[inline(always)]
329 pub fn clear_attribute(&mut self) -> &mut Self {
330 self.get_mut_attributes().clear();
331 self
332 }
333
334 /// Retrieves an internal framework attribute.
335 ///
336 /// # Arguments
337 ///
338 /// - `InternalAttribute` - The internal attribute key to retrieve.
339 ///
340 /// # Returns
341 ///
342 /// - `Option<V>` - The attribute value if it exists and can be cast to the specified type.
343 #[inline(always)]
344 fn try_get_internal_attribute<V>(&self, key: InternalAttribute) -> Option<V>
345 where
346 V: AnySendSyncClone,
347 {
348 self.get_attributes()
349 .get(&Attribute::Internal(key).to_string())
350 .and_then(|arc: &ArcAnySendSync| arc.downcast_ref::<V>())
351 .cloned()
352 }
353
354 /// Retrieves an internal framework attribute.
355 ///
356 /// # Arguments
357 ///
358 /// - `InternalAttribute` - The internal attribute key to retrieve.
359 ///
360 /// # Returns
361 ///
362 /// - `AnySendSyncClone` - The attribute value if it exists and can be cast to the specified type.
363 ///
364 /// # Panics
365 ///
366 /// - If the attribute is not found.
367 #[inline(always)]
368 fn get_internal_attribute<V>(&self, key: InternalAttribute) -> V
369 where
370 V: AnySendSyncClone,
371 {
372 self.try_get_internal_attribute(key).unwrap()
373 }
374
375 /// Sets an internal framework attribute.
376 ///
377 /// # Arguments
378 ///
379 /// - `InternalAttribute` - The internal attribute key to set.
380 /// - `AnySendSyncClone` - The value of the attribute.
381 ///
382 /// # Returns
383 ///
384 /// - `&mut Self` - A reference to the modified context.
385 #[inline(always)]
386 fn set_internal_attribute<V>(&mut self, key: InternalAttribute, value: V) -> &mut Self
387 where
388 V: AnySendSyncClone,
389 {
390 self.get_mut_attributes()
391 .insert(Attribute::Internal(key).to_string(), Arc::new(value));
392 self
393 }
394
395 /// Stores panic data for the current task context.
396 ///
397 /// # Arguments
398 ///
399 /// - `PanicData` - The panic data specific to the current task.
400 ///
401 /// # Returns
402 ///
403 /// - `&mut Self` - Reference to the modified context for method chaining.
404 #[inline(always)]
405 pub fn set_task_panic(&mut self, panic_data: PanicData) -> &mut Self {
406 self.set_internal_attribute(InternalAttribute::TaskPanicData, panic_data)
407 }
408
409 /// Retrieves panic data associated with the current task.
410 ///
411 /// # Returns
412 ///
413 /// - `Option<PanicData>` - Task panic data if a panic was caught during execution.
414 #[inline(always)]
415 pub fn try_get_task_panic_data(&self) -> Option<PanicData> {
416 self.try_get_internal_attribute(InternalAttribute::TaskPanicData)
417 }
418
419 /// Retrieves panic data associated with the current task.
420 ///
421 /// # Returns
422 ///
423 /// - `PanicData` - Task panic data if available.
424 ///
425 /// # Panics
426 ///
427 /// - If no task panic data is found.
428 #[inline(always)]
429 pub fn get_task_panic_data(&self) -> PanicData {
430 self.get_internal_attribute(InternalAttribute::TaskPanicData)
431 }
432
433 /// Sets the request error information for the context.
434 ///
435 /// # Arguments
436 ///
437 /// - `RequestError` - The request error information to store.
438 ///
439 /// # Returns
440 ///
441 /// - `&mut Self` - A reference to the modified context.
442 #[inline(always)]
443 pub(crate) fn set_request_error_data(&mut self, request_error: RequestError) -> &mut Self {
444 self.set_internal_attribute(InternalAttribute::RequestErrorData, request_error)
445 }
446
447 /// Retrieves request error information if an error occurred during handling.
448 ///
449 /// # Returns
450 ///
451 /// - `Option<RequestError>` - The request error information if an error was caught.
452 #[inline(always)]
453 pub fn try_get_request_error_data(&self) -> Option<RequestError> {
454 self.try_get_internal_attribute(InternalAttribute::RequestErrorData)
455 }
456
457 /// Retrieves request error information if an error occurred during handling.
458 ///
459 /// # Returns
460 ///
461 /// - `RequestError` - The request error information if an error was caught.
462 ///
463 /// # Panics
464 ///
465 /// - If the request error information is not found.
466 #[inline(always)]
467 pub fn get_request_error_data(&self) -> RequestError {
468 self.get_internal_attribute(InternalAttribute::RequestErrorData)
469 }
470}