Skip to main content

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}