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}