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