http_body_request_validator/
buffering_validator.rs

1//! [`BufferingValidator`] implementation and associated types.
2
3use crate::AsBuf as _;
4
5/// An error that can occur while validating the request.
6#[derive(Debug)]
7pub enum Error<B, V> {
8    /// The buffering of the request body failed.
9    BodyBuffering(B),
10    /// The validation failed.
11    Validation(V),
12}
13
14/// The trivial [`crate::convert::BufferedToBody`] implementation for a given bufferer.
15pub type TrivialBufferedToOutBodyFor<Bufferer, InBody> =
16    crate::convert::Trivial<crate::bufferer::BufferedFor<Bufferer, InBody>>;
17
18/// The buffering validator.
19pub struct BufferingValidator<
20    Bufferer,
21    InBody,
22    BufferedToOutBody = TrivialBufferedToOutBodyFor<Bufferer, InBody>,
23> {
24    /// The bufferer.
25    pub bufferer: Bufferer,
26
27    /// The phantom data types.
28    pub phantom_data: core::marker::PhantomData<(fn() -> InBody, BufferedToOutBody)>,
29}
30
31impl<Bufferer, InBody>
32    BufferingValidator<Bufferer, InBody, TrivialBufferedToOutBodyFor<Bufferer, InBody>>
33where
34    InBody: http_body::Body,
35    Bufferer: crate::Bufferer<InBody>,
36{
37    /// Create a new [`BufferingValidator`] with trivial `BufferedToOutBody`.
38    pub const fn new(bufferer: Bufferer) -> Self {
39        Self {
40            bufferer,
41            phantom_data: core::marker::PhantomData,
42        }
43    }
44}
45
46impl<Bufferer, InBody, BufferedToOutBody> BufferingValidator<Bufferer, InBody, BufferedToOutBody>
47where
48    InBody: http_body::Body,
49    Bufferer: crate::Bufferer<InBody>,
50{
51    /// Change the `BufferedToOutBody` type.
52    pub fn with_buffered_to_out_body<New>(self) -> BufferingValidator<Bufferer, InBody, New> {
53        let Self {
54            bufferer,
55            phantom_data: _,
56        } = self;
57        BufferingValidator {
58            bufferer,
59            phantom_data: core::marker::PhantomData,
60        }
61    }
62}
63
64impl<Bufferer, InBody, BufferedToOutBody> BufferingValidator<Bufferer, InBody, BufferedToOutBody>
65where
66    InBody: http_body::Body,
67    Bufferer: crate::Bufferer<InBody>,
68    BufferedToOutBody:
69        crate::convert::BufferedToBody<Buffered = crate::bufferer::BufferedFor<Bufferer, InBody>>,
70{
71    /// Validate the given request.
72    ///
73    /// Takes the `InBody` out of the request, buffers it, validates the buffered body data using
74    /// the specified validator, and then converts the buffered stuff with `BufferedToOutBody` to
75    /// get the `BufferedToOutBody::Body` type.
76    pub async fn validate<Validator>(
77        &self,
78        validator: Validator,
79        req: http::Request<InBody>,
80    ) -> Result<http::Request<BufferedToOutBody::Body>, Error<Bufferer::Error, Validator::Error>>
81    where
82        Validator: http_request_validator::Validator<crate::bufferer::DataFor<Bufferer, InBody>>,
83    {
84        let (parts, body) = req.into_parts();
85
86        let buffered = self
87            .bufferer
88            .buffer(body)
89            .await
90            .map_err(Error::BodyBuffering)?;
91
92        validator
93            .validate(&parts, buffered.as_buf())
94            .await
95            .map_err(Error::Validation)?;
96
97        let req = http::Request::from_parts(parts, BufferedToOutBody::buffered_to_body(buffered));
98
99        Ok(req)
100    }
101}