• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gengteng / axum-valid / 6586130410

20 Oct 2023 09:46AM UTC coverage: 82.548% (-6.7%) from 89.277%
6586130410

push

github

gengteng
add support for validify

214 of 214 new or added lines in 7 files covered. (100.0%)

1173 of 1421 relevant lines covered (82.55%)

12.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.0
/src/query.rs
1
//! # Support for `Query<T>`
2
//!
3
//! ## Feature
4
//!
5
//! Enable the `query` feature (enabled by default) to use `Valid<Query<T>>`.
6
//!
7
//! ## Usage
8
//!
9
//! 1. Implement `Deserialize` and `Validate` for your data type `T`.
10
//! 2. In your handler function, use `Valid<Query<T>>` as some parameter's type.
11
//!
12
//! ## Example
13
//!
14
//! ```no_run
15
//! #[cfg(feature = "validator")]
16
//! mod validator_example {
17
//!     use axum::extract::Query;
18
//!     use axum::routing::post;
19
//!     use axum::Router;
20
//!     use axum_valid::Valid;
21
//!     use serde::Deserialize;
22
//!     use validator::Validate;
23
//!
24
//!     pub fn router() -> Router {
25
//!         Router::new().route("/query", post(handler))
26
//!     }
27
//!
28
//!     async fn handler(Valid(Query(parameter)): Valid<Query<Parameter>>) {
29
//!         assert!(parameter.validate().is_ok());
30
//!         // Support automatic dereferencing
31
//!         println!("v0 = {}, v1 = {}", parameter.v0, parameter.v1);
32
//!     }
33
//!
34
//!     #[derive(Validate, Deserialize)]
35
//!     pub struct Parameter {
36
//!         #[validate(range(min = 5, max = 10))]
37
//!         pub v0: i32,
38
//!         #[validate(length(min = 1, max = 10))]
39
//!         pub v1: String,
40
//!     }
41
//! }
42
//!
43
//! #[cfg(feature = "garde")]
44
//! mod garde_example {
45
//!     use axum::routing::post;
46
//!     use axum::extract::Query;
47
//!     use axum::Router;
48
//!     use axum_valid::Garde;
49
//!     use serde::Deserialize;
50
//!     use garde::Validate;
51
//!
52
//!     pub fn router() -> Router {
53
//!         Router::new().route("/query", post(handler))
54
//!     }
55
//!
56
//!     async fn handler(Garde(Query(parameter)): Garde<Query<Parameter>>) {
57
//!         assert!(parameter.validate(&()).is_ok());
58
//!         // Support automatic dereferencing
59
//!         println!("v0 = {}, v1 = {}", parameter.v0, parameter.v1);
60
//!     }
61
//!
62
//!     #[derive(Validate, Deserialize)]
63
//!     pub struct Parameter {
64
//!         #[garde(range(min = 5, max = 10))]
65
//!         pub v0: i32,
66
//!         #[garde(length(min = 1, max = 10))]
67
//!         pub v1: String,
68
//!     }
69
//! }
70
//!
71
//! # #[tokio::main]
72
//! # async fn main() -> anyhow::Result<()> {
73
//! #     use axum::Router;
74
//! #     let router = Router::new();
75
//! #     #[cfg(feature = "validator")]
76
//! #     let router = router.nest("/validator", validator_example::router());
77
//! #     #[cfg(feature = "garde")]
78
//! #     let router = router.nest("/garde", garde_example::router());
79
//! #     axum::Server::bind(&([0u8, 0, 0, 0], 8080).into())
80
//! #         .serve(router.into_make_service())
81
//! #         .await?;
82
//! #     Ok(())
83
//! # }
84
//! ```
85

86
use crate::HasValidate;
87
#[cfg(feature = "validator")]
88
use crate::HasValidateArgs;
89
use axum::extract::Query;
90
#[cfg(feature = "validator")]
91
use validator::ValidateArgs;
92

93
impl<T> HasValidate for Query<T> {
94
    type Validate = T;
95
    fn get_validate(&self) -> &T {
10✔
96
        &self.0
×
97
    }
98
}
99

100
#[cfg(feature = "validator")]
101
impl<'v, T: ValidateArgs<'v>> HasValidateArgs<'v> for Query<T> {
102
    type ValidateArgs = T;
103
    fn get_validate_args(&self) -> &Self::ValidateArgs {
4✔
104
        &self.0
×
105
    }
106
}
107

108
#[cfg(feature = "validify")]
109
impl<T: validify::Modify> crate::HasModify for Query<T> {
110
    type Modify = T;
111

112
    fn get_modify(&mut self) -> &mut Self::Modify {
3✔
113
        &mut self.0
×
114
    }
115
}
116

117
#[cfg(feature = "validify")]
118
impl<T> crate::PayloadExtractor for Query<T> {
119
    type Payload = T;
120

121
    fn get_payload(self) -> Self::Payload {
3✔
122
        self.0
3✔
123
    }
124
}
125

126
#[cfg(feature = "validify")]
127
impl<T: validify::Validify> crate::HasValidify for Query<T> {
128
    type Validify = T;
129
    type PayloadExtractor = Query<T::Payload>;
130

131
    fn from_validified(v: Self::Validify) -> Self {
3✔
132
        Query(v)
3✔
133
    }
134
}
135

136
#[cfg(test)]
137
mod tests {
138
    use crate::tests::{ValidTest, ValidTestParameter};
139
    use axum::extract::Query;
140
    use axum::http::StatusCode;
141
    use reqwest::RequestBuilder;
142
    use serde::Serialize;
143

144
    impl<T: ValidTestParameter + Serialize> ValidTest for Query<T> {
145
        const ERROR_STATUS_CODE: StatusCode = StatusCode::BAD_REQUEST;
146

147
        fn set_valid_request(builder: RequestBuilder) -> RequestBuilder {
148
            builder.query(&T::valid())
149
        }
150

151
        fn set_error_request(builder: RequestBuilder) -> RequestBuilder {
152
            builder.query(T::error())
153
        }
154

155
        fn set_invalid_request(builder: RequestBuilder) -> RequestBuilder {
156
            builder.query(&T::invalid())
157
        }
158
    }
159
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc