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    /// - `&'a 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    /// - `&Self` - 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 Self` - 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    /// - `T` - 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    /// - `T` - 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    /// - `K` - 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, K>(&self, key: K) -> Option<V>
251    where
252        V: AnySendSyncClone,
253        K: AsRef<str>,
254    {
255        self.get_attributes()
256            .get(&Attribute::External(key.as_ref().to_owned()).to_string())
257            .and_then(|arc: &ArcAnySendSync| arc.downcast_ref::<V>())
258            .cloned()
259    }
260
261    /// Retrieves a specific attribute by its key, casting it to the specified type, panicking if not found.
262    ///
263    /// # Arguments
264    ///
265    /// - `K` - The key of the attribute to retrieve.
266    ///
267    /// # Returns
268    ///
269    /// - `V` - The attribute value if it exists and can be cast to the specified type.
270    ///
271    /// # Panics
272    ///
273    /// - If the attribute is not found.
274    #[inline(always)]
275    pub fn get_attribute<V, K>(&self, key: K) -> V
276    where
277        V: AnySendSyncClone,
278        K: AsRef<str>,
279    {
280        self.try_get_attribute(key).unwrap()
281    }
282
283    /// Sets an attribute in the context.
284    ///
285    /// # Arguments
286    ///
287    /// - `K` - The key of the attribute to set.
288    /// - `V` - The value of the attribute.
289    ///
290    /// # Returns
291    ///
292    /// - `&mut Self` - A reference to the modified context.
293    #[inline(always)]
294    pub fn set_attribute<K, V>(&mut self, key: K, value: V) -> &mut Self
295    where
296        K: AsRef<str>,
297        V: AnySendSyncClone,
298    {
299        self.get_mut_attributes().insert(
300            Attribute::External(key.as_ref().to_owned()).to_string(),
301            Arc::new(value),
302        );
303        self
304    }
305
306    /// Removes an attribute from the context.
307    ///
308    /// # Arguments
309    ///
310    /// - `K` - The key of the attribute to remove.
311    ///
312    /// # Returns
313    ///
314    /// - `&mut Self` - A reference to the modified context.
315    #[inline(always)]
316    pub fn remove_attribute<K>(&mut self, key: K) -> &mut Self
317    where
318        K: AsRef<str>,
319    {
320        self.get_mut_attributes()
321            .remove(&Attribute::External(key.as_ref().to_owned()).to_string());
322        self
323    }
324
325    /// Clears all attributes from the context.
326    ///
327    /// # Returns
328    ///
329    /// - `&mut Self` - A reference to the modified context.
330    #[inline(always)]
331    pub fn clear_attribute(&mut self) -> &mut Self {
332        self.get_mut_attributes().clear();
333        self
334    }
335
336    /// Retrieves an internal framework attribute.
337    ///
338    /// # Arguments
339    ///
340    /// - `InternalAttribute` - The internal attribute key to retrieve.
341    ///
342    /// # Returns
343    ///
344    /// - `Option<V>` - The attribute value if it exists and can be cast to the specified type.
345    #[inline(always)]
346    fn try_get_internal_attribute<V>(&self, key: InternalAttribute) -> Option<V>
347    where
348        V: AnySendSyncClone,
349    {
350        self.get_attributes()
351            .get(&Attribute::Internal(key).to_string())
352            .and_then(|arc: &ArcAnySendSync| arc.downcast_ref::<V>())
353            .cloned()
354    }
355
356    /// Retrieves an internal framework attribute.
357    ///
358    /// # Arguments
359    ///
360    /// - `InternalAttribute` - The internal attribute key to retrieve.
361    ///
362    /// # Returns
363    ///
364    /// - `V` - The attribute value if it exists and can be cast to the specified type.
365    ///
366    /// # Panics
367    ///
368    /// - If the attribute is not found.
369    #[inline(always)]
370    fn get_internal_attribute<V>(&self, key: InternalAttribute) -> V
371    where
372        V: AnySendSyncClone,
373    {
374        self.try_get_internal_attribute(key).unwrap()
375    }
376
377    /// Sets an internal framework attribute.
378    ///
379    /// # Arguments
380    ///
381    /// - `InternalAttribute` - The internal attribute key to set.
382    /// - `V` - The value of the attribute.
383    ///
384    /// # Returns
385    ///
386    /// - `&mut Self` - A reference to the modified context.
387    #[inline(always)]
388    fn set_internal_attribute<V>(&mut self, key: InternalAttribute, value: V) -> &mut Self
389    where
390        V: AnySendSyncClone,
391    {
392        self.get_mut_attributes()
393            .insert(Attribute::Internal(key).to_string(), Arc::new(value));
394        self
395    }
396
397    /// Stores panic data for the current task context.
398    ///
399    /// # Arguments
400    ///
401    /// - `PanicData` - The panic data specific to the current task.
402    ///
403    /// # Returns
404    ///
405    /// - `&mut Self` - Reference to the modified context for method chaining.
406    #[inline(always)]
407    pub fn set_task_panic(&mut self, panic_data: PanicData) -> &mut Self {
408        self.set_internal_attribute(InternalAttribute::TaskPanicData, panic_data)
409    }
410
411    /// Retrieves panic data associated with the current task.
412    ///
413    /// # Returns
414    ///
415    /// - `Option<PanicData>` - Task panic data if a panic was caught during execution.
416    #[inline(always)]
417    pub fn try_get_task_panic_data(&self) -> Option<PanicData> {
418        self.try_get_internal_attribute(InternalAttribute::TaskPanicData)
419    }
420
421    /// Retrieves panic data associated with the current task.
422    ///
423    /// # Returns
424    ///
425    /// - `PanicData` - Task panic data if available.
426    ///
427    /// # Panics
428    ///
429    /// - If no task panic data is found.
430    #[inline(always)]
431    pub fn get_task_panic_data(&self) -> PanicData {
432        self.get_internal_attribute(InternalAttribute::TaskPanicData)
433    }
434
435    /// Sets the request error information for the context.
436    ///
437    /// # Arguments
438    ///
439    /// - `RequestError` - The request error information to store.
440    ///
441    /// # Returns
442    ///
443    /// - `&mut Self` - A reference to the modified context.
444    #[inline(always)]
445    pub(crate) fn set_request_error_data(&mut self, request_error: RequestError) -> &mut Self {
446        self.set_internal_attribute(InternalAttribute::RequestErrorData, request_error)
447    }
448
449    /// Retrieves request error information if an error occurred during handling.
450    ///
451    /// # Returns
452    ///
453    /// - `Option<RequestError>` - The request error information if an error was caught.
454    #[inline(always)]
455    pub fn try_get_request_error_data(&self) -> Option<RequestError> {
456        self.try_get_internal_attribute(InternalAttribute::RequestErrorData)
457    }
458
459    /// Retrieves request error information if an error occurred during handling.
460    ///
461    /// # Returns
462    ///
463    /// - `RequestError` - The request error information if an error was caught.
464    ///
465    /// # Panics
466    ///
467    /// - If the request error information is not found.
468    #[inline(always)]
469    pub fn get_request_error_data(&self) -> RequestError {
470        self.get_internal_attribute(InternalAttribute::RequestErrorData)
471    }
472}