forked from LukeMathWalker/pavex
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pre-processing middleware (LukeMathWalker#214)
The missing piece in our middleware story.
- Loading branch information
1 parent
eef2220
commit dbe9683
Showing
49 changed files
with
1,923 additions
and
364 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
mod registered; | ||
mod unregistered; | ||
|
||
pub use registered::RegisteredPostProcessingMiddleware; | ||
pub use unregistered::PostProcessingMiddleware; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
use crate::blueprint::conversions::raw_callable2registered_callable; | ||
use crate::blueprint::reflection::RawCallable; | ||
use pavex_bp_schema::{Blueprint as BlueprintSchema, Component, PostProcessingMiddleware}; | ||
|
||
/// The type returned by [`Blueprint::post_process`]. | ||
/// | ||
/// It allows you to further configure the behaviour of post-processing middleware | ||
/// you just registered. | ||
/// | ||
/// [`Blueprint::post_process`]: crate::blueprint::Blueprint::post_process | ||
pub struct RegisteredPostProcessingMiddleware<'a> { | ||
pub(crate) blueprint: &'a mut BlueprintSchema, | ||
/// The index of the registered middleware in the blueprint's `components` vector. | ||
pub(crate) component_id: usize, | ||
} | ||
|
||
impl<'a> RegisteredPostProcessingMiddleware<'a> { | ||
#[track_caller] | ||
/// Register an error handler. | ||
/// | ||
/// If an error handler has already been registered for this middleware, it will be | ||
/// overwritten. | ||
/// | ||
/// # Guide | ||
/// | ||
/// Check out the ["Error handlers"](https://pavex.dev/docs/guide/errors/error_handlers) | ||
/// section of Pavex's guide for a thorough introduction to error handlers | ||
/// in Pavex applications. | ||
/// | ||
/// # Example | ||
/// | ||
/// ```rust | ||
/// use pavex::{f, blueprint::Blueprint}; | ||
/// use pavex::response::Response; | ||
/// # struct SizeError; | ||
/// | ||
/// // 👇 a fallible post-processing middleware | ||
/// fn max_response_size(response: Response) -> Result<Response, SizeError> | ||
/// { | ||
/// // [...] | ||
/// # todo!() | ||
/// } | ||
/// | ||
/// fn error_to_response(error: &SizeError) -> Response { | ||
/// // [...] | ||
/// # todo!() | ||
/// } | ||
/// | ||
/// # fn main() { | ||
/// let mut bp = Blueprint::new(); | ||
/// bp.post_process(f!(crate::max_response_size)) | ||
/// .error_handler(f!(crate::error_to_response)); | ||
/// # } | ||
/// ``` | ||
pub fn error_handler(mut self, error_handler: RawCallable) -> Self { | ||
let callable = raw_callable2registered_callable(error_handler); | ||
self.post_processing_middleware().error_handler = Some(callable); | ||
self | ||
} | ||
|
||
fn post_processing_middleware(&mut self) -> &mut PostProcessingMiddleware { | ||
let component = &mut self.blueprint.components[self.component_id]; | ||
let Component::PostProcessingMiddleware(c) = component else { | ||
unreachable!("The component should be a post-processing middleware") | ||
}; | ||
c | ||
} | ||
} |
52 changes: 1 addition & 51 deletions
52
.../src/blueprint/middleware/unregistered.rs → ...blueprint/middleware/post/unregistered.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
mod registered; | ||
mod unregistered; | ||
|
||
pub use registered::RegisteredPreProcessingMiddleware; | ||
pub use unregistered::PreProcessingMiddleware; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use crate::blueprint::conversions::raw_callable2registered_callable; | ||
use crate::blueprint::reflection::RawCallable; | ||
use pavex_bp_schema::{Blueprint as BlueprintSchema, Component, PreProcessingMiddleware}; | ||
|
||
/// The type returned by [`Blueprint::pre_process`]. | ||
/// | ||
/// It allows you to further configure the behaviour of the registered pre-processing | ||
/// middleware. | ||
/// | ||
/// [`Blueprint::pre_process`]: crate::blueprint::Blueprint::pre_process | ||
pub struct RegisteredPreProcessingMiddleware<'a> { | ||
pub(crate) blueprint: &'a mut BlueprintSchema, | ||
/// The index of the registered middleware in the blueprint's `components` vector. | ||
pub(crate) component_id: usize, | ||
} | ||
|
||
impl<'a> RegisteredPreProcessingMiddleware<'a> { | ||
#[track_caller] | ||
/// Register an error handler. | ||
/// | ||
/// If an error handler has already been registered for this middleware, it will be | ||
/// overwritten. | ||
/// | ||
/// # Guide | ||
/// | ||
/// Check out the ["Error handlers"](https://pavex.dev/docs/guide/errors/error_handlers) | ||
/// section of Pavex's guide for a thorough introduction to error handlers | ||
/// in Pavex applications. | ||
/// | ||
/// # Example | ||
/// | ||
/// ```rust | ||
/// use pavex::{f, blueprint::Blueprint, middleware::Processing}; | ||
/// use pavex::request::RequestHead; | ||
/// use pavex::response::Response; | ||
/// # struct LogLevel; | ||
/// # struct AuthError; | ||
/// | ||
/// // 👇 a fallible middleware | ||
/// fn reject_anonymous(request_head: &RequestHead) -> Result<Processing, AuthError> | ||
/// { | ||
/// // [...] | ||
/// # todo!() | ||
/// } | ||
/// | ||
/// fn error_to_response(error: &AuthError, log_level: LogLevel) -> Response { | ||
/// // [...] | ||
/// # todo!() | ||
/// } | ||
/// | ||
/// # fn main() { | ||
/// let mut bp = Blueprint::new(); | ||
/// bp.wrap(f!(crate::reject_anonymous)) | ||
/// .error_handler(f!(crate::error_to_response)); | ||
/// # } | ||
/// ``` | ||
pub fn error_handler(mut self, error_handler: RawCallable) -> Self { | ||
let callable = raw_callable2registered_callable(error_handler); | ||
self.pre_processing_middleware().error_handler = Some(callable); | ||
self | ||
} | ||
|
||
fn pre_processing_middleware(&mut self) -> &mut PreProcessingMiddleware { | ||
let component = &mut self.blueprint.components[self.component_id]; | ||
let Component::PreProcessingMiddleware(c) = component else { | ||
unreachable!("The component should be a pre-processing middleware") | ||
}; | ||
c | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use crate::blueprint::conversions::raw_callable2registered_callable; | ||
use crate::blueprint::middleware::pre::RegisteredPreProcessingMiddleware; | ||
use crate::blueprint::reflection::RawCallable; | ||
use crate::blueprint::Blueprint; | ||
use pavex_bp_schema::Callable; | ||
|
||
/// A pre-processing middleware that has been configured but has not yet been registered with a [`Blueprint`]. | ||
/// | ||
/// # Guide | ||
/// | ||
/// Check out [`Blueprint::pre_process`] for an introduction to pre_processing middlewares in Pavex. | ||
/// | ||
/// # Use cases | ||
/// | ||
/// [`PreProcessingMiddleware`] is primarily used by | ||
/// [kits](https://pavex.dev/docs/guide/dependency_injection/core_concepts/kits) | ||
/// to allow users to customize (or disable!) | ||
/// the bundled middlewares **before** registering them with a [`Blueprint`]. | ||
#[derive(Clone, Debug)] | ||
pub struct PreProcessingMiddleware { | ||
pub(in crate::blueprint) callable: Callable, | ||
pub(in crate::blueprint) error_handler: Option<Callable>, | ||
} | ||
|
||
impl PreProcessingMiddleware { | ||
/// Create a new (unregistered) pre_processing middleware. | ||
/// | ||
/// Check out the documentation of [`Blueprint::pre_process`] for more details | ||
/// on pre-processing middlewares. | ||
#[track_caller] | ||
pub fn new(callable: RawCallable) -> Self { | ||
Self { | ||
callable: raw_callable2registered_callable(callable), | ||
error_handler: None, | ||
} | ||
} | ||
|
||
/// Register an error handler for this middleware. | ||
/// | ||
/// Check out the documentation of [`RegisteredPreProcessingMiddleware::error_handler`] for more details. | ||
#[track_caller] | ||
pub fn error_handler(mut self, error_handler: RawCallable) -> Self { | ||
self.error_handler = Some(raw_callable2registered_callable(error_handler)); | ||
self | ||
} | ||
|
||
/// Register this middleware with a [`Blueprint`]. | ||
/// | ||
/// Check out the documentation of [`Blueprint::pre_process`] for more details. | ||
pub fn register(self, bp: &mut Blueprint) -> RegisteredPreProcessingMiddleware { | ||
bp.register_pre_processing_middleware(self) | ||
} | ||
} |
Oops, something went wrong.