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

gengteng / axum-valid / 6456231901

09 Oct 2023 11:53AM UTC coverage: 89.07% (+17.9%) from 71.154%
6456231901

push

github

gengteng
refactor Rejections

25 of 25 new or added lines in 3 files covered. (100.0%)

766 of 860 relevant lines covered (89.07%)

13.46 hits per line

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

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

93
use crate::HasValidate;
94
#[cfg(feature = "validator")]
95
use crate::HasValidateArgs;
96
use axum_msgpack::{MsgPack, MsgPackRaw};
97
#[cfg(feature = "validator")]
98
use validator::ValidateArgs;
99

100
impl<T> HasValidate for MsgPack<T> {
101
    type Validate = T;
102
    fn get_validate(&self) -> &T {
6✔
103
        &self.0
×
104
    }
105
}
106

107
#[cfg(feature = "validator")]
108
impl<'v, T: ValidateArgs<'v>> HasValidateArgs<'v> for MsgPack<T> {
109
    type ValidateArgs = T;
110
    fn get_validate_args(&self) -> &Self::ValidateArgs {
3✔
111
        &self.0
×
112
    }
113
}
114

115
impl<T> HasValidate for MsgPackRaw<T> {
116
    type Validate = T;
117
    fn get_validate(&self) -> &T {
6✔
118
        &self.0
×
119
    }
120
}
121

122
#[cfg(feature = "validator")]
123
impl<'v, T: ValidateArgs<'v>> HasValidateArgs<'v> for MsgPackRaw<T> {
124
    type ValidateArgs = T;
125
    fn get_validate_args(&self) -> &Self::ValidateArgs {
3✔
126
        &self.0
×
127
    }
128
}
129

130
#[cfg(test)]
131
mod tests {
132
    use crate::tests::{ValidTest, ValidTestParameter};
133
    use axum::http::StatusCode;
134
    use axum_msgpack::{MsgPack, MsgPackRaw};
135
    use reqwest::RequestBuilder;
136
    use serde::Serialize;
137

138
    impl<T: ValidTestParameter + Serialize> ValidTest for MsgPack<T> {
139
        const ERROR_STATUS_CODE: StatusCode = StatusCode::BAD_REQUEST;
140

141
        fn set_valid_request(builder: RequestBuilder) -> RequestBuilder {
142
            builder
143
                .header(reqwest::header::CONTENT_TYPE, "application/msgpack")
144
                .body(
145
                    rmp_serde::to_vec_named(T::valid())
146
                        .expect("Failed to serialize parameters to msgpack"),
147
                )
148
        }
149

150
        fn set_error_request(builder: RequestBuilder) -> RequestBuilder {
151
            // `Content-Type` not set, `MsgPack` should return `415 Unsupported Media Type`
152
            builder
153
        }
154

155
        fn set_invalid_request(builder: RequestBuilder) -> RequestBuilder {
156
            builder
157
                .header(reqwest::header::CONTENT_TYPE, "application/msgpack")
158
                .body(
159
                    rmp_serde::to_vec_named(T::invalid())
160
                        .expect("Failed to serialize parameters to msgpack"),
161
                )
162
        }
163
    }
164

165
    impl<T: ValidTestParameter + Serialize> ValidTest for MsgPackRaw<T> {
166
        const ERROR_STATUS_CODE: StatusCode = StatusCode::BAD_REQUEST;
167

168
        fn set_valid_request(builder: RequestBuilder) -> RequestBuilder {
169
            builder
170
                .header(reqwest::header::CONTENT_TYPE, "application/msgpack")
171
                .body(
172
                    rmp_serde::to_vec(T::valid())
173
                        .expect("Failed to serialize parameters to msgpack"),
174
                )
175
        }
176

177
        fn set_error_request(builder: RequestBuilder) -> RequestBuilder {
178
            // `Content-Type` not set, `MsgPack` should return `415 Unsupported Media Type`
179
            builder
180
        }
181

182
        fn set_invalid_request(builder: RequestBuilder) -> RequestBuilder {
183
            builder
184
                .header(reqwest::header::CONTENT_TYPE, "application/msgpack")
185
                .body(
186
                    rmp_serde::to_vec(T::invalid())
187
                        .expect("Failed to serialize parameters to msgpack"),
188
                )
189
        }
190
    }
191
}
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