Module axum_valid::extra

source ·
Expand description

§Support for extractors from axum-extra

§Feature

Enable the extra feature to use Valid<Cached<T>>, Valid<WithRejection<T, R>> and WithRejection<Valid<T>, R>.

§Modules

§Cached<T> and WithRejection<T, R>

§Valid<Cached<T>>

§Usage
  1. Implement your own extractor T.
  2. Implement Clone and Validate for your extractor type T.
  3. In your handler function, use Valid<Cached<T>> as some parameter’s type.
§Example
#[cfg(feature = "validator")]
mod validator_example {
    use axum::extract::FromRequestParts;
    use axum::http::request::Parts;
    use axum::response::{IntoResponse, Response};
    use axum::routing::post;
    use axum::Router;
    use axum_extra::extract::Cached;
    use axum_valid::Valid;
    use validator::Validate;

    pub fn router() -> Router {
        Router::new().route("/cached", post(handler))
    }

    async fn handler(Valid(Cached(parameter)): Valid<Cached<Parameter>>) {
        assert!(parameter.validate().is_ok());
    }

    #[derive(Validate, Clone)]
    pub struct Parameter {
        #[validate(range(min = 5, max = 10))]
        pub v0: i32,
        #[validate(length(min = 1, max = 10))]
        pub v1: String,
    }

    pub struct ParameterRejection;

    impl IntoResponse for ParameterRejection {
        fn into_response(self) -> Response {
            todo!()
        }
    }

    #[axum::async_trait]
    impl<S> FromRequestParts<S> for Parameter
    where
        S: Send + Sync,
    {
        type Rejection = ParameterRejection;

        async fn from_request_parts(_parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
            todo!()
        }
    }
}
#[cfg(feature = "garde")]
mod garde_example {
    use axum::extract::FromRequestParts;
    use axum::http::request::Parts;
    use axum::response::{IntoResponse, Response};
    use axum::routing::post;
    use axum::Router;
    use axum_extra::extract::Cached;
    use axum_valid::Garde;
    use garde::Validate;

    pub fn router() -> Router {
        Router::new().route("/cached", post(handler))
    }

    async fn handler(Garde(Cached(parameter)): Garde<Cached<Parameter>>) {
        assert!(parameter.validate(&()).is_ok());
    }

    #[derive(Validate, Clone)]
    pub struct Parameter {
        #[garde(range(min = 5, max = 10))]
        pub v0: i32,
        #[garde(length(min = 1, max = 10))]
        pub v1: String,
    }

    pub struct ParameterRejection;

    impl IntoResponse for ParameterRejection {
        fn into_response(self) -> Response {
            todo!()
        }
    }

    #[axum::async_trait]
    impl<S> FromRequestParts<S> for Parameter
    where
        S: Send + Sync,
    {
        type Rejection = ParameterRejection;

        async fn from_request_parts(_parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
            todo!()
        }
    }
}

§Valid<WithRejection<T, R>>

§Usage
  1. Implement your own extractor T and rejection type R.
  2. Implement Validate for your extractor type T.
  3. In your handler function, use Valid<WithRejection<T, R>> as some parameter’s type.
§Example
#[cfg(feature = "validator")]
mod validator_example {
    use axum::extract::FromRequestParts;
    use axum::http::request::Parts;
    use axum::http::StatusCode;
    use axum::response::{IntoResponse, Response};
    use axum::routing::post;
    use axum::Router;
    use axum_extra::extract::WithRejection;
    use axum_valid::Valid;
    use validator::Validate;

    pub fn router() -> Router {
        Router::new().route("/valid_with_rejection", post(handler))
    }

    async fn handler(
        Valid(WithRejection(parameter, _)): Valid<
            WithRejection<Parameter, ValidWithRejectionRejection>,
        >,
    ) {
        assert!(parameter.validate().is_ok());
    }

    #[derive(Validate)]
    pub struct Parameter {
        #[validate(range(min = 5, max = 10))]
        pub v0: i32,
        #[validate(length(min = 1, max = 10))]
        pub v1: String,
    }

    pub struct ValidWithRejectionRejection;

    impl IntoResponse for ValidWithRejectionRejection {
        fn into_response(self) -> Response {
            StatusCode::BAD_REQUEST.into_response()
        }
    }

    #[axum::async_trait]
    impl<S> FromRequestParts<S> for Parameter
    where
        S: Send + Sync,
    {
        type Rejection = ValidWithRejectionRejection;

        async fn from_request_parts(_parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
            todo!()
        }
    }
}

#[cfg(feature = "garde")]
mod garde_example {
    use axum::extract::FromRequestParts;
    use axum::http::request::Parts;
    use axum::http::StatusCode;
    use axum::response::{IntoResponse, Response};
    use axum::routing::post;
    use axum::Router;
    use axum_extra::extract::WithRejection;
    use axum_valid::Garde;
    use garde::Validate;

    pub fn router() -> Router {
        Router::new().route("/valid_with_rejection", post(handler))
    }

    async fn handler(
        Garde(WithRejection(parameter, _)): Garde<
            WithRejection<Parameter, ValidWithRejectionRejection>,
        >,
    ) {
        assert!(parameter.validate(&()).is_ok());
    }

    #[derive(Validate)]
    pub struct Parameter {
        #[garde(range(min = 5, max = 10))]
        pub v0: i32,
        #[garde(length(min = 1, max = 10))]
        pub v1: String,
    }

    pub struct ValidWithRejectionRejection;

    impl IntoResponse for ValidWithRejectionRejection {
        fn into_response(self) -> Response {
            StatusCode::BAD_REQUEST.into_response()
        }
    }

    #[axum::async_trait]
    impl<S> FromRequestParts<S> for Parameter
    where
        S: Send + Sync,
    {
        type Rejection = ValidWithRejectionRejection;

        async fn from_request_parts(_parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
            todo!()
        }
    }
}

§WithRejection<Valid<T>, R>

§Usage
  1. Implement your own extractor T and rejection type R.
  2. Implement Validate and HasValidate for your extractor type T.
  3. Implement From<ValidRejection<T::Rejection>> for R.
  4. In your handler function, use WithRejection<Valid<T>, R> as some parameter’s type.
§Example
#[cfg(feature = "validator")]
mod validator_example {
    use axum::extract::FromRequestParts;
    use axum::http::request::Parts;
    use axum::response::{IntoResponse, Response};
    use axum::routing::post;
    use axum::Router;
    use axum_extra::extract::WithRejection;
    use axum_valid::{HasValidate, Valid, ValidRejection};
    use validator::Validate;

    pub fn router() -> Router {
        Router::new().route("/with_rejection_valid", post(handler))
    }

    async fn handler(
        WithRejection(Valid(parameter), _): WithRejection<
            Valid<Parameter>,
            WithRejectionValidRejection,
        >,
    ) {
        assert!(parameter.validate().is_ok());
    }

    #[derive(Validate)]
    pub struct Parameter {
        #[validate(range(min = 5, max = 10))]
        pub v0: i32,
        #[validate(length(min = 1, max = 10))]
        pub v1: String,
    }

    impl HasValidate for Parameter {
        type Validate = Self;

        fn get_validate(&self) -> &Self::Validate {
            self
        }
    }

    pub struct ParameterRejection;

    impl IntoResponse for ParameterRejection {
        fn into_response(self) -> Response {
            todo!()
        }
    }

    #[axum::async_trait]
    impl<S> FromRequestParts<S> for Parameter
    where
        S: Send + Sync,
    {
        type Rejection = ParameterRejection;

        async fn from_request_parts(_parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
            todo!()
        }
    }

    pub struct WithRejectionValidRejection;

    impl From<ValidRejection<ParameterRejection>> for WithRejectionValidRejection {
        fn from(_inner: ValidRejection<ParameterRejection>) -> Self {
            todo!()
        }
    }

    impl IntoResponse for WithRejectionValidRejection {
        fn into_response(self) -> Response {
            todo!()
        }
    }
}

#[cfg(feature = "garde")]
mod garde_example {
    use axum::extract::FromRequestParts;
    use axum::http::request::Parts;
    use axum::response::{IntoResponse, Response};
    use axum::routing::post;
    use axum::Router;
    use axum_extra::extract::WithRejection;
    use axum_valid::{HasValidate, Garde, GardeRejection};
    use garde::Validate;

    pub fn router() -> Router {
        Router::new().route("/with_rejection_valid", post(handler))
    }

    async fn handler(
        WithRejection(Garde(parameter), _): WithRejection<
            Garde<Parameter>,
            WithRejectionGardeRejection,
        >,
    ) {
        assert!(parameter.validate(&()).is_ok());
    }

    #[derive(Validate)]
    pub struct Parameter {
        #[garde(range(min = 5, max = 10))]
        pub v0: i32,
        #[garde(length(min = 1, max = 10))]
        pub v1: String,
    }

    impl HasValidate for Parameter {
        type Validate = Self;

        fn get_validate(&self) -> &Self::Validate {
            self
        }
    }

    pub struct ParameterRejection;

    impl IntoResponse for ParameterRejection {
        fn into_response(self) -> Response {
            todo!()
        }
    }

    #[axum::async_trait]
    impl<S> FromRequestParts<S> for Parameter
    where
        S: Send + Sync,
    {
        type Rejection = ParameterRejection;

        async fn from_request_parts(_parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
            todo!()
        }
    }

    pub struct WithRejectionGardeRejection;

    impl From<GardeRejection<ParameterRejection>> for WithRejectionGardeRejection {
        fn from(_inner: GardeRejection<ParameterRejection>) -> Self {
            todo!()
        }
    }

    impl IntoResponse for WithRejectionGardeRejection {
        fn into_response(self) -> Response {
            todo!()
        }
    }
}

Modules§

  • Support for Form<T> from axum-extra
  • Support for Protobuf<T> from axum-extra
  • Support for Query<T> from axum-extra
  • Support for T: TypedPath from axum-extra