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}