pavex/blueprint/post.rs
1use crate::blueprint::ErrorHandler;
2use crate::blueprint::conversions::coordinates2coordinates;
3use pavex_bp_schema::{Blueprint as BlueprintSchema, Component, Location};
4
5use super::reflection::AnnotationCoordinates;
6
7/// The input type for [`Blueprint::post_process`].
8///
9/// Check out [`Blueprint::post_process`] for more information on post-processing middlewares
10/// in Pavex.
11///
12/// # Stability guarantees
13///
14/// Use the [`post_process`](macro@crate::post_process) attribute macro to create instances of `PostProcessingMiddleware`.\
15/// `PostProcessingMiddleware`'s fields are an implementation detail of Pavex's macros and should not be relied upon:
16/// newer versions of Pavex may add, remove or modify its fields.
17///
18/// [`Blueprint::post_process`]: crate::Blueprint::post_process
19pub struct PostProcessingMiddleware {
20 #[doc(hidden)]
21 pub coordinates: AnnotationCoordinates,
22}
23
24/// The type returned by [`Blueprint::post_process`].
25///
26/// It allows you to further configure the behaviour of post-processing middleware
27/// you just registered.
28///
29/// [`Blueprint::post_process`]: crate::Blueprint::post_process
30pub struct RegisteredPostProcessingMiddleware<'a> {
31 pub(crate) blueprint: &'a mut BlueprintSchema,
32 /// The index of the registered middleware in the blueprint's `components` vector.
33 pub(crate) component_id: usize,
34}
35
36impl RegisteredPostProcessingMiddleware<'_> {
37 #[track_caller]
38 /// Register an error handler.
39 ///
40 /// If an error handler has already been registered for this middleware, it will be
41 /// overwritten.
42 ///
43 /// # Guide
44 ///
45 /// Check out the ["Error handlers"](https://pavex.dev/docs/guide/errors/error_handlers)
46 /// section of Pavex's guide for a thorough introduction to error handlers
47 /// in Pavex applications.
48 ///
49 /// # Example
50 ///
51 /// ```rust
52 /// use pavex::Blueprint;
53 /// use pavex::{error_handler, post_process};
54 /// use pavex::Response;
55 /// # struct SizeError;
56 ///
57 /// // 👇 a fallible post-processing middleware
58 /// #[post_process]
59 /// pub fn max_response_size(response: Response) -> Result<Response, SizeError>
60 /// {
61 /// // [...]
62 /// # todo!()
63 /// }
64 ///
65 /// #[error_handler]
66 /// pub fn size_error_handler(error: &SizeError) -> Response {
67 /// // [...]
68 /// # todo!()
69 /// }
70 ///
71 /// # fn main() {
72 /// let mut bp = Blueprint::new();
73 /// bp.post_process(MAX_RESPONSE_SIZE)
74 /// .error_handler(SIZE_ERROR_HANDLER);
75 /// # }
76 /// ```
77 pub fn error_handler(mut self, error_handler: ErrorHandler) -> Self {
78 let error_handler = pavex_bp_schema::ErrorHandler {
79 coordinates: coordinates2coordinates(error_handler.coordinates),
80 registered_at: Location::caller(),
81 };
82 self.post_processing_middleware().error_handler = Some(error_handler);
83 self
84 }
85
86 fn post_processing_middleware(&mut self) -> &mut pavex_bp_schema::PostProcessingMiddleware {
87 let component = &mut self.blueprint.components[self.component_id];
88 let Component::PostProcessingMiddleware(c) = component else {
89 unreachable!("The component should be a post-processing middleware")
90 };
91 c
92 }
93}