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

gengteng / axum-valid / 7081856309

04 Dec 2023 04:03AM UTC coverage: 90.75% (+1.7%) from 89.034%
7081856309

push

github

gengteng
docs: update README.md

1560 of 1719 relevant lines covered (90.75%)

13.77 hits per line

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

94.94
/src/validify/test.rs
1
#![cfg(feature = "validify")]
2

3
use crate::tests::{ValidTest, ValidTestParameter};
4
use crate::{
5
    HasValidate, Modified, Validated, Validified, ValidifiedByRef, VALIDATION_ERROR_STATUS,
6
};
7
use axum::extract::{Path, Query};
8
use axum::http::StatusCode;
9
use axum::routing::{get, post};
10
use axum::{Form, Json, Router};
11
use hyper::Method;
12
use once_cell::sync::Lazy;
13
use reqwest::Url;
14
use serde::{Deserialize, Serialize};
15
use std::any::type_name;
16
use std::net::SocketAddr;
17
use std::ops::Deref;
18
use tokio::net::TcpListener;
19
use validify::{Modify, Validate, Validify};
20

21
#[derive(Clone, Deserialize, Serialize, Validify, Eq, PartialEq)]
22
#[cfg_attr(feature = "extra_protobuf", derive(prost::Message))]
23
#[cfg_attr(
24
    feature = "typed_multipart",
25
    derive(axum_typed_multipart::TryFromMultipart)
26
)]
27
pub struct ParametersValidify {
28
    #[validate(range(min = 5.0, max = 10.0))]
29
    #[cfg_attr(feature = "extra_protobuf", prost(int32, tag = "1"))]
30
    v0: i32,
31
    #[modify(lowercase)]
32
    #[validate(length(min = 1, max = 10))]
33
    #[cfg_attr(feature = "extra_protobuf", prost(string, tag = "2"))]
34
    v1: String,
35
}
36

37
trait IsModified: Modify + Clone + PartialEq + Eq {
38
    fn modified(&self) -> bool {
9✔
39
        let mut cloned = self.clone();
9✔
40
        cloned.modify();
9✔
41
        cloned == *self
9✔
42
    }
43
}
44

45
impl<T> IsModified for T where T: Modify + Clone + PartialEq + Eq {}
46

47
static VALID_PARAMETERS: Lazy<ParametersValidify> = Lazy::new(|| ParametersValidify {
6✔
48
    v0: 5,
49
    v1: String::from("ABCDEFG"),
3✔
50
});
51

52
static INVALID_PARAMETERS: Lazy<ParametersValidify> = Lazy::new(|| ParametersValidify {
6✔
53
    v0: 6,
54
    v1: String::from("ABCDEFGHIJKLMN"),
3✔
55
});
56

57
impl ValidTestParameter for ParametersValidify {
58
    fn valid() -> &'static Self {
3✔
59
        VALID_PARAMETERS.deref()
3✔
60
    }
61

62
    fn error() -> &'static [(&'static str, &'static str)] {
63
        &[("not_v0_or_v1", "value")]
64
    }
65

66
    fn invalid() -> &'static Self {
3✔
67
        INVALID_PARAMETERS.deref()
3✔
68
    }
69
}
70

71
impl HasValidate for ParametersValidify {
72
    type Validate = ParametersValidify;
73

74
    fn get_validate(&self) -> &Self::Validate {
3✔
75
        self
76
    }
77
}
78

79
#[tokio::test]
18✔
80
async fn test_main() -> anyhow::Result<()> {
9✔
81
    let router = Router::new()
51✔
82
        .route(route::PATH, get(extract_path))
6✔
83
        .route(route::PATH_MODIFIED, get(extract_path_modified))
6✔
84
        .route(route::PATH_VALIDIFIED, get(extract_path_validified))
6✔
85
        .route(
86
            route::PATH_VALIDIFIED_BY_REF,
87
            get(extract_path_validified_by_ref),
3✔
88
        )
89
        .route(route::QUERY, get(extract_query))
6✔
90
        .route(route::QUERY_MODIFIED, get(extract_query_modified))
6✔
91
        .route(route::QUERY_VALIDIFIED, get(extract_query_validified))
6✔
92
        .route(
93
            route::QUERY_VALIDIFIED_BY_REF,
94
            get(extract_query_validified_by_ref),
3✔
95
        )
96
        .route(route::FORM, post(extract_form))
6✔
97
        .route(route::FORM_MODIFIED, post(extract_form_modified))
6✔
98
        .route(route::FORM_VALIDIFIED, post(extract_form_validified))
6✔
99
        .route(
100
            route::FORM_VALIDIFIED_BY_REF,
101
            post(extract_form_validified_by_ref),
3✔
102
        )
103
        .route(route::JSON, post(extract_json))
6✔
104
        .route(route::JSON_MODIFIED, post(extract_json_modified))
6✔
105
        .route(route::JSON_VALIDIFIED, post(extract_json_validified))
6✔
106
        .route(
107
            route::JSON_VALIDIFIED_BY_REF,
108
            post(extract_json_validified_by_ref),
3✔
109
        );
110

111
    #[cfg(feature = "typed_header")]
112
    let router = router
12✔
113
        .route(
114
            typed_header::route::TYPED_HEADER,
115
            post(typed_header::extract_typed_header),
3✔
116
        )
117
        .route(
118
            typed_header::route::TYPED_HEADER_MODIFIED,
119
            post(typed_header::extract_typed_header_modified),
3✔
120
        )
121
        .route(
122
            typed_header::route::TYPED_HEADER_VALIDIFIED_BY_REF,
123
            post(typed_header::extract_typed_header_validified_by_ref),
3✔
124
        );
125

126
    #[cfg(feature = "typed_multipart")]
127
    let router = router
21✔
128
        .route(
129
            typed_multipart::route::TYPED_MULTIPART,
130
            post(typed_multipart::extract_typed_multipart),
3✔
131
        )
132
        .route(
133
            typed_multipart::route::TYPED_MULTIPART_MODIFIED,
134
            post(typed_multipart::extract_typed_multipart_modified),
3✔
135
        )
136
        .route(
137
            typed_multipart::route::TYPED_MULTIPART_VALIDIFIED_BY_REF,
138
            post(typed_multipart::extract_typed_multipart_validified_by_ref),
3✔
139
        )
140
        .route(
141
            typed_multipart::route::BASE_MULTIPART,
142
            post(typed_multipart::extract_base_multipart),
3✔
143
        )
144
        .route(
145
            typed_multipart::route::BASE_MULTIPART_MODIFIED,
146
            post(typed_multipart::extract_base_multipart_modified),
3✔
147
        )
148
        .route(
149
            typed_multipart::route::BASE_MULTIPART_VALIDIFIED_BY_REF,
150
            post(typed_multipart::extract_base_multipart_validified_by_ref),
3✔
151
        );
152

153
    #[cfg(feature = "extra")]
154
    let router = router
30✔
155
        .route(extra::route::CACHED, post(extra::extract_cached))
6✔
156
        .route(
157
            extra::route::CACHED_MODIFIED,
158
            post(extra::extract_cached_modified),
3✔
159
        )
160
        .route(
161
            extra::route::CACHED_VALIDIFIED_BY_REF,
162
            post(extra::extract_cached_validified_by_ref),
3✔
163
        )
164
        .route(
165
            extra::route::WITH_REJECTION,
166
            post(extra::extract_with_rejection),
3✔
167
        )
168
        .route(
169
            extra::route::WITH_REJECTION_MODIFIED,
170
            post(extra::extract_with_rejection_modified),
3✔
171
        )
172
        .route(
173
            extra::route::WITH_REJECTION_VALIDIFIED_BY_REF,
174
            post(extra::extract_with_rejection_validified_by_ref),
3✔
175
        )
176
        .route(
177
            extra::route::WITH_REJECTION_VALIDIFY,
178
            post(extra::extract_with_rejection_validifiy),
3✔
179
        )
180
        .route(
181
            extra::route::WITH_REJECTION_VALIDIFY_MODIFIED,
182
            post(extra::extract_with_rejection_validifiy_modified),
3✔
183
        )
184
        .route(
185
            extra::route::WITH_REJECTION_VALIDIFY_VALIDIFIED_BY_REF,
186
            post(extra::extract_with_rejection_validifiy_validified_by_ref),
3✔
187
        );
188

189
    #[cfg(feature = "extra_typed_path")]
190
    let router = router
12✔
191
        .route(
192
            extra_typed_path::route::EXTRA_TYPED_PATH,
193
            get(extra_typed_path::extract_extra_typed_path),
3✔
194
        )
195
        .route(
196
            extra_typed_path::route::EXTRA_TYPED_PATH_MODIFIED,
197
            get(extra_typed_path::extract_extra_typed_path_modified),
3✔
198
        )
199
        .route(
200
            extra_typed_path::route::EXTRA_TYPED_PATH_VALIDIFIED_BY_REF,
201
            get(extra_typed_path::extract_extra_typed_path_validified_by_ref),
3✔
202
        );
203

204
    #[cfg(feature = "extra_query")]
205
    let router = router
15✔
206
        .route(
207
            extra_query::route::EXTRA_QUERY,
208
            post(extra_query::extract_extra_query),
3✔
209
        )
210
        .route(
211
            extra_query::route::EXTRA_QUERY_MODIFIED,
212
            post(extra_query::extract_extra_query_modified),
3✔
213
        )
214
        .route(
215
            extra_query::route::EXTRA_QUERY_VALIDIFIED,
216
            post(extra_query::extract_extra_query_validified),
3✔
217
        )
218
        .route(
219
            extra_query::route::EXTRA_QUERY_VALIDIFIED_BY_REF,
220
            post(extra_query::extract_extra_query_validified_by_ref),
3✔
221
        );
222

223
    #[cfg(feature = "extra_form")]
224
    let router = router
15✔
225
        .route(
226
            extra_form::route::EXTRA_FORM,
227
            post(extra_form::extract_extra_form),
3✔
228
        )
229
        .route(
230
            extra_form::route::EXTRA_FORM_MODIFIED,
231
            post(extra_form::extract_extra_form_modified),
3✔
232
        )
233
        .route(
234
            extra_form::route::EXTRA_FORM_VALIDIFED,
235
            post(extra_form::extract_extra_form_validifed),
3✔
236
        )
237
        .route(
238
            extra_form::route::EXTRA_FORM_VALIDIFED_BY_REF,
239
            post(extra_form::extract_extra_form_validifed_by_ref),
3✔
240
        );
241

242
    #[cfg(feature = "extra_protobuf")]
243
    let router = router
12✔
244
        .route(
245
            extra_protobuf::route::EXTRA_PROTOBUF,
246
            post(extra_protobuf::extract_extra_protobuf),
3✔
247
        )
248
        .route(
249
            extra_protobuf::route::EXTRA_PROTOBUF_MODIFIED,
250
            post(extra_protobuf::extract_extra_protobuf_modified),
3✔
251
        )
252
        .route(
253
            extra_protobuf::route::EXTRA_PROTOBUF_VALIDIFIED_BY_REF,
254
            post(extra_protobuf::extract_extra_protobuf_validified_by_ref),
3✔
255
        );
256

257
    #[cfg(feature = "yaml")]
258
    let router = router
15✔
259
        .route(yaml::route::YAML, post(yaml::extract_yaml))
6✔
260
        .route(
261
            yaml::route::YAML_MODIFIED,
262
            post(yaml::extract_yaml_modified),
3✔
263
        )
264
        .route(
265
            yaml::route::YAML_VALIDIFIED,
266
            post(yaml::extract_yaml_validified),
3✔
267
        )
268
        .route(
269
            yaml::route::YAML_VALIDIFIED_BY_REF,
270
            post(yaml::extract_yaml_validified_by_ref),
3✔
271
        );
272

273
    #[cfg(feature = "msgpack")]
274
    let router = router
27✔
275
        .route(msgpack::route::MSGPACK, post(msgpack::extract_msgpack))
6✔
276
        .route(
277
            msgpack::route::MSGPACK_MODIFIED,
278
            post(msgpack::extract_msgpack_modified),
3✔
279
        )
280
        .route(
281
            msgpack::route::MSGPACK_VALIDIFIED,
282
            post(msgpack::extract_msgpack_validified),
3✔
283
        )
284
        .route(
285
            msgpack::route::MSGPACK_VALIDIFIED_BY_REF,
286
            post(msgpack::extract_msgpack_validified_by_ref),
3✔
287
        )
288
        .route(
289
            msgpack::route::MSGPACK_RAW,
290
            post(msgpack::extract_msgpack_raw),
3✔
291
        )
292
        .route(
293
            msgpack::route::MSGPACK_RAW_MODIFIED,
294
            post(msgpack::extract_msgpack_raw_modified),
3✔
295
        )
296
        .route(
297
            msgpack::route::MSGPACK_RAW_VALIDIFIED,
298
            post(msgpack::extract_msgpack_raw_validified),
3✔
299
        )
300
        .route(
301
            msgpack::route::MSGPACK_RAW_VALIDIFIED_BY_REF,
302
            post(msgpack::extract_msgpack_raw_validified_by_ref),
3✔
303
        );
304

305
    #[cfg(feature = "xml")]
306
    let router = router
15✔
307
        .route(xml::route::XML, post(xml::extract_xml))
6✔
308
        .route(xml::route::XML_MODIFIED, post(xml::extract_xml_modified))
6✔
309
        .route(
310
            xml::route::XML_VALIDIFIED,
311
            post(xml::extract_xml_validified),
3✔
312
        )
313
        .route(
314
            xml::route::XML_VALIDIFIED_BY_REF,
315
            post(xml::extract_xml_validified_by_ref),
3✔
316
        );
317

318
    #[cfg(feature = "toml")]
319
    let router = router
15✔
320
        .route(toml::route::TOML, post(toml::extract_toml))
6✔
321
        .route(
322
            toml::route::TOML_MODIFIED,
323
            post(toml::extract_toml_modified),
3✔
324
        )
325
        .route(
326
            toml::route::TOML_VALIDIFIED,
327
            post(toml::extract_toml_validified),
3✔
328
        )
329
        .route(
330
            toml::route::TOML_VALIDIFIED_BY_REF,
331
            post(toml::extract_toml_validified_by_ref),
3✔
332
        );
333

334
    let listener = TcpListener::bind(&SocketAddr::from(([0u8, 0, 0, 0], 0u16))).await?;
6✔
335
    let server_addr = listener.local_addr()?;
6✔
336
    let server = axum::serve(listener, router.into_make_service());
3✔
337
    println!("Axum server address: {}.", server_addr);
6✔
338

339
    tokio::spawn(async move {
12✔
340
        let _ = server.await;
9✔
341
    });
342

343
    let server_url = format!("http://{}", server_addr);
6✔
344
    let test_executor = TestExecutor::from(Url::parse(&format!("http://{}", server_addr))?);
6✔
345

346
    async fn test_extra_path(
3✔
347
        test_executor: &TestExecutor,
348
        route: &str,
349
        server_url: &str,
350
    ) -> anyhow::Result<()> {
351
        do_test_extra_path(
352
            test_executor,
353
            route,
354
            server_url,
355
            StatusCode::OK,
356
            StatusCode::BAD_REQUEST,
357
            VALIDATION_ERROR_STATUS,
358
            true,
359
        )
360
        .await
9✔
361
    }
362

363
    async fn test_extra_path_modified(
3✔
364
        test_executor: &TestExecutor,
365
        route: &str,
366
        server_url: &str,
367
    ) -> anyhow::Result<()> {
368
        do_test_extra_path(
369
            test_executor,
370
            route,
371
            server_url,
372
            StatusCode::OK,
373
            StatusCode::BAD_REQUEST,
374
            StatusCode::OK,
375
            false,
376
        )
377
        .await
9✔
378
    }
379

380
    async fn test_extra_path_validified(
3✔
381
        test_executor: &TestExecutor,
382
        route: &str,
383
        server_url: &str,
384
    ) -> anyhow::Result<()> {
385
        do_test_extra_path(
386
            test_executor,
387
            route,
388
            server_url,
389
            StatusCode::OK,
390
            StatusCode::BAD_REQUEST,
391
            VALIDATION_ERROR_STATUS,
392
            true,
393
        )
394
        .await
9✔
395
    }
396

397
    async fn do_test_extra_path(
3✔
398
        test_executor: &TestExecutor,
399
        route: &str,
400
        server_url: &str,
401
        expected_valid_status: StatusCode,
402
        expected_error_status: StatusCode,
403
        expected_invalid_status: StatusCode,
404
        should_check_json: bool,
405
    ) -> anyhow::Result<()> {
406
        let path_type_name = type_name::<Path<ParametersValidify>>();
6✔
407
        let valid_path_response = test_executor
12✔
408
            .client()
409
            .get(format!(
21✔
410
                "{}/{route}/{}/{}",
411
                server_url, VALID_PARAMETERS.v0, VALID_PARAMETERS.v1
6✔
412
            ))
413
            .send()
414
            .await?;
9✔
415
        assert_eq!(
3✔
416
            valid_path_response.status().as_u16(),
6✔
417
            expected_valid_status.as_u16(),
3✔
418
            "Valid '{}' test failed.",
419
            path_type_name
420
        );
421

422
        let error_path_response = test_executor
12✔
423
            .client()
424
            .get(format!("{}/{route}/not_i32/path", server_url))
9✔
425
            .send()
426
            .await?;
9✔
427
        assert_eq!(
6✔
428
            error_path_response.status().as_u16(),
6✔
429
            expected_error_status.as_u16(),
3✔
430
            "Error '{}' test failed: {}",
431
            path_type_name,
432
            error_path_response.text().await?
×
433
        );
434

435
        let invalid_path_response = test_executor
12✔
436
            .client()
437
            .get(format!(
21✔
438
                "{}/{route}/{}/{}",
439
                server_url, INVALID_PARAMETERS.v0, INVALID_PARAMETERS.v1
6✔
440
            ))
441
            .send()
442
            .await?;
9✔
443
        assert_eq!(
3✔
444
            invalid_path_response.status().as_u16(),
6✔
445
            expected_invalid_status.as_u16(),
3✔
446
            "Invalid '{}' test failed.",
447
            path_type_name
448
        );
449
        if should_check_json {
2✔
450
            #[cfg(feature = "into_json")]
451
            check_json(path_type_name, invalid_path_response).await;
2✔
452
        }
453
        println!("All {} tests passed.", path_type_name);
6✔
454
        Ok(())
3✔
455
    }
456

457
    test_extra_path(&test_executor, "path", &server_url).await?;
6✔
458
    test_extra_path_modified(&test_executor, "path_modified", &server_url).await?;
9✔
459
    test_extra_path_validified(&test_executor, "path_validified", &server_url).await?;
9✔
460
    test_extra_path(&test_executor, "path_validified_by_ref", &server_url).await?;
9✔
461

462
    // Validated
463
    test_executor
12✔
464
        .execute::<Query<ParametersValidify>>(Method::GET, route::QUERY)
3✔
465
        .await?;
9✔
466
    // Modified
467
    test_executor
12✔
468
        .execute_modified::<Query<ParametersValidify>>(Method::GET, route::QUERY_MODIFIED)
3✔
469
        .await?;
9✔
470
    // ValidifiedByRef
471
    test_executor
12✔
472
        .execute::<Query<ParametersValidify>>(Method::GET, route::QUERY_VALIDIFIED_BY_REF)
3✔
473
        .await?;
9✔
474
    // Validified
475
    test_executor
12✔
476
        .execute_validified::<Query<ParametersValidify>>(Method::GET, route::QUERY_VALIDIFIED)
3✔
477
        .await?;
9✔
478

479
    // Validated
480
    test_executor
12✔
481
        .execute::<Form<ParametersValidify>>(Method::POST, route::FORM)
3✔
482
        .await?;
9✔
483
    // Modified
484
    test_executor
12✔
485
        .execute_modified::<Form<ParametersValidify>>(Method::POST, route::FORM_MODIFIED)
3✔
486
        .await?;
9✔
487
    // ValidifiedByRef
488
    test_executor
12✔
489
        .execute::<Form<ParametersValidify>>(Method::POST, route::FORM_VALIDIFIED_BY_REF)
3✔
490
        .await?;
9✔
491
    // Validified
492
    test_executor
12✔
493
        .execute_validified::<Form<ParametersValidify>>(Method::POST, route::FORM_VALIDIFIED)
3✔
494
        .await?;
9✔
495

496
    // Validated
497
    test_executor
12✔
498
        .execute::<Json<ParametersValidify>>(Method::POST, route::JSON)
3✔
499
        .await?;
9✔
500
    // Modified
501
    test_executor
12✔
502
        .execute_modified::<Json<ParametersValidify>>(Method::POST, route::JSON_MODIFIED)
3✔
503
        .await?;
9✔
504
    // ValidifiedByRef
505
    test_executor
12✔
506
        .execute::<Json<ParametersValidify>>(Method::POST, route::JSON_VALIDIFIED_BY_REF)
3✔
507
        .await?;
9✔
508
    // Validified
509
    test_executor
12✔
510
        .execute_validified::<Json<ParametersValidify>>(Method::POST, route::JSON_VALIDIFIED)
3✔
511
        .await?;
9✔
512

513
    #[cfg(feature = "typed_header")]
514
    {
515
        use axum_extra::typed_header::TypedHeader;
516
        // Validated
517
        test_executor
12✔
518
            .execute::<TypedHeader<ParametersValidify>>(
519
                Method::POST,
3✔
520
                typed_header::route::TYPED_HEADER,
521
            )
522
            .await?;
9✔
523
        // Modified
524
        test_executor
12✔
525
            .execute_modified::<TypedHeader<ParametersValidify>>(
526
                Method::POST,
3✔
527
                typed_header::route::TYPED_HEADER_MODIFIED,
528
            )
529
            .await?;
9✔
530
        // ValidifiedByRef
531
        test_executor
12✔
532
            .execute::<TypedHeader<ParametersValidify>>(
533
                Method::POST,
3✔
534
                typed_header::route::TYPED_HEADER_VALIDIFIED_BY_REF,
535
            )
536
            .await?;
9✔
537
    }
538

539
    #[cfg(feature = "typed_multipart")]
540
    {
541
        use axum_typed_multipart::{BaseMultipart, TypedMultipart, TypedMultipartError};
542

543
        // Validated
544
        test_executor
12✔
545
            .execute::<BaseMultipart<ParametersValidify, TypedMultipartError>>(
546
                Method::POST,
3✔
547
                typed_multipart::route::BASE_MULTIPART,
548
            )
549
            .await?;
9✔
550
        // Modified
551
        test_executor
12✔
552
            .execute_modified::<BaseMultipart<ParametersValidify, TypedMultipartError>>(
553
                Method::POST,
3✔
554
                typed_multipart::route::BASE_MULTIPART_MODIFIED,
555
            )
556
            .await?;
9✔
557
        // ValidifiedByRef
558
        test_executor
12✔
559
            .execute::<BaseMultipart<ParametersValidify, TypedMultipartError>>(
560
                Method::POST,
3✔
561
                typed_multipart::route::BASE_MULTIPART_VALIDIFIED_BY_REF,
562
            )
563
            .await?;
9✔
564

565
        // Validated
566
        test_executor
12✔
567
            .execute::<TypedMultipart<ParametersValidify>>(
568
                Method::POST,
3✔
569
                typed_multipart::route::TYPED_MULTIPART,
570
            )
571
            .await?;
9✔
572
        // Modified
573
        test_executor
12✔
574
            .execute_modified::<TypedMultipart<ParametersValidify>>(
575
                Method::POST,
3✔
576
                typed_multipart::route::TYPED_MULTIPART_MODIFIED,
577
            )
578
            .await?;
9✔
579
        // ValidifiedByRef
580
        test_executor
12✔
581
            .execute::<TypedMultipart<ParametersValidify>>(
582
                Method::POST,
3✔
583
                typed_multipart::route::TYPED_MULTIPART_VALIDIFIED_BY_REF,
584
            )
585
            .await?;
9✔
586
    }
587

588
    #[cfg(feature = "extra")]
589
    {
590
        use axum_extra::extract::{Cached, WithRejection};
591
        use extra::{
592
            ParametersRejection, ValidifyWithRejectionRejection, WithRejectionValidifyRejection,
593
        };
594
        // Validated
595
        test_executor
12✔
596
            .execute::<Cached<ParametersValidify>>(Method::POST, extra::route::CACHED)
3✔
597
            .await?;
9✔
598
        // Modified
599
        test_executor
12✔
600
            .execute_modified::<Cached<ParametersValidify>>(
601
                Method::POST,
3✔
602
                extra::route::CACHED_MODIFIED,
603
            )
604
            .await?;
9✔
605
        // ValidifiedByRef
606
        test_executor
12✔
607
            .execute::<Cached<ParametersValidify>>(
608
                Method::POST,
3✔
609
                extra::route::CACHED_VALIDIFIED_BY_REF,
610
            )
611
            .await?;
9✔
612

613
        // Validated
614
        test_executor
12✔
615
            .execute::<WithRejection<ParametersValidify, ValidifyWithRejectionRejection>>(
616
                Method::POST,
3✔
617
                extra::route::WITH_REJECTION,
618
            )
619
            .await?;
9✔
620
        // Modified
621
        test_executor
12✔
622
            .execute_modified::<WithRejection<ParametersValidify, ValidifyWithRejectionRejection>>(
623
                Method::POST,
3✔
624
                extra::route::WITH_REJECTION_MODIFIED,
625
            )
626
            .await?;
9✔
627
        // ValidifiedByRef
628
        test_executor
12✔
629
            .execute::<WithRejection<ParametersValidify, ValidifyWithRejectionRejection>>(
630
                Method::POST,
3✔
631
                extra::route::WITH_REJECTION_VALIDIFIED_BY_REF,
632
            )
633
            .await?;
9✔
634

635
        // Validated
636
        test_executor
12✔
637
            .execute::<WithRejection<
638
                Validated<ParametersValidify>,
639
                WithRejectionValidifyRejection<ParametersRejection>,
640
            >>(Method::POST, extra::route::WITH_REJECTION_VALIDIFY)
3✔
641
            .await?;
9✔
642
        // Modified
643
        test_executor
12✔
644
            .execute_modified::<WithRejection<
645
                Modified<ParametersValidify>,
646
                ValidifyWithRejectionRejection,
647
            >>(Method::POST, extra::route::WITH_REJECTION_VALIDIFY_MODIFIED)
3✔
648
            .await?;
9✔
649
        // ValidifiedByRef
650
        test_executor
12✔
651
            .execute::<WithRejection<
652
                ValidifiedByRef<ParametersValidify>,
653
                WithRejectionValidifyRejection<ParametersRejection>,
654
            >>(
655
                Method::POST,
3✔
656
                extra::route::WITH_REJECTION_VALIDIFY_VALIDIFIED_BY_REF,
657
            )
658
            .await?;
9✔
659
    }
660

661
    #[cfg(feature = "extra_typed_path")]
662
    {
663
        async fn test_extra_typed_path(
3✔
664
            test_executor: &TestExecutor,
665
            route: &str,
666
            server_url: &str,
667
        ) -> anyhow::Result<()> {
668
            do_test_extra_typed_path(
669
                test_executor,
670
                route,
671
                server_url,
672
                StatusCode::OK,
673
                StatusCode::BAD_REQUEST,
674
                VALIDATION_ERROR_STATUS,
675
                true,
676
            )
677
            .await
9✔
678
        }
679

680
        async fn test_extra_typed_path_modified(
3✔
681
            test_executor: &TestExecutor,
682
            route: &str,
683
            server_url: &str,
684
        ) -> anyhow::Result<()> {
685
            do_test_extra_typed_path(
686
                test_executor,
687
                route,
688
                server_url,
689
                StatusCode::OK,
690
                StatusCode::BAD_REQUEST,
691
                StatusCode::OK,
692
                false,
693
            )
694
            .await
9✔
695
        }
696

697
        async fn do_test_extra_typed_path(
3✔
698
            test_executor: &TestExecutor,
699
            route: &str,
700
            server_url: &str,
701
            expected_valid_status: StatusCode,
702
            expected_error_status: StatusCode,
703
            expected_invalid_status: StatusCode,
704
            should_check_json: bool,
705
        ) -> anyhow::Result<()> {
706
            let extra_typed_path_type_name = "T: TypedPath";
3✔
707
            let valid_extra_typed_path_response = test_executor
12✔
708
                .client()
709
                .get(format!(
21✔
710
                    "{}/{route}/{}/{}",
711
                    server_url, VALID_PARAMETERS.v0, VALID_PARAMETERS.v1
6✔
712
                ))
713
                .send()
714
                .await?;
9✔
715
            assert_eq!(
3✔
716
                valid_extra_typed_path_response.status().as_u16(),
6✔
717
                expected_valid_status.as_u16(),
3✔
718
                "Validified '{}' test failed.",
719
                extra_typed_path_type_name
720
            );
721

722
            let error_extra_typed_path_response = test_executor
12✔
723
                .client()
724
                .get(format!("{}/{route}/not_i32/path", server_url))
9✔
725
                .send()
726
                .await?;
9✔
727
            assert_eq!(
3✔
728
                error_extra_typed_path_response.status().as_u16(),
6✔
729
                expected_error_status.as_u16(),
3✔
730
                "Error '{}' test failed.",
731
                extra_typed_path_type_name
732
            );
733

734
            let invalid_extra_typed_path_response = test_executor
12✔
735
                .client()
736
                .get(format!(
21✔
737
                    "{}/{route}/{}/{}",
738
                    server_url, INVALID_PARAMETERS.v0, INVALID_PARAMETERS.v1
6✔
739
                ))
740
                .send()
741
                .await?;
9✔
742
            assert_eq!(
3✔
743
                invalid_extra_typed_path_response.status().as_u16(),
6✔
744
                expected_invalid_status.as_u16(),
3✔
745
                "Invalid '{}' test failed.",
746
                extra_typed_path_type_name
747
            );
748

749
            if should_check_json {
2✔
750
                #[cfg(feature = "into_json")]
751
                check_json(
752
                    extra_typed_path_type_name,
2✔
753
                    invalid_extra_typed_path_response,
2✔
754
                )
755
                .await;
2✔
756
            }
757
            println!("All {} tests passed.", extra_typed_path_type_name);
6✔
758
            Ok(())
3✔
759
        }
760

761
        test_extra_typed_path(&test_executor, "extra_typed_path", &server_url).await?;
9✔
762
        test_extra_typed_path_modified(&test_executor, "extra_typed_path_modified", &server_url)
12✔
763
            .await?;
9✔
764
        test_extra_typed_path(
765
            &test_executor,
3✔
766
            "extra_typed_path_validified_by_ref",
767
            &server_url,
3✔
768
        )
769
        .await?;
9✔
770
    }
771

772
    #[cfg(feature = "extra_query")]
773
    {
774
        use axum_extra::extract::Query;
775
        // Validated
776
        test_executor
12✔
777
            .execute::<Query<ParametersValidify>>(Method::POST, extra_query::route::EXTRA_QUERY)
3✔
778
            .await?;
9✔
779
        // Modified
780
        test_executor
12✔
781
            .execute_modified::<Query<ParametersValidify>>(
782
                Method::POST,
3✔
783
                extra_query::route::EXTRA_QUERY_MODIFIED,
784
            )
785
            .await?;
9✔
786
        // Validified
787
        test_executor
12✔
788
            .execute_validified::<Query<ParametersValidify>>(
789
                Method::POST,
3✔
790
                extra_query::route::EXTRA_QUERY_VALIDIFIED,
791
            )
792
            .await?;
9✔
793
        // ValidifiedByRef
794
        test_executor
12✔
795
            .execute::<Query<ParametersValidify>>(
796
                Method::POST,
3✔
797
                extra_query::route::EXTRA_QUERY_VALIDIFIED_BY_REF,
798
            )
799
            .await?;
9✔
800
    }
801

802
    #[cfg(feature = "extra_form")]
803
    {
804
        use axum_extra::extract::Form;
805
        // Validated
806
        test_executor
12✔
807
            .execute::<Form<ParametersValidify>>(Method::POST, extra_form::route::EXTRA_FORM)
3✔
808
            .await?;
9✔
809
        // Modified
810
        test_executor
12✔
811
            .execute_modified::<Form<ParametersValidify>>(
812
                Method::POST,
3✔
813
                extra_form::route::EXTRA_FORM_MODIFIED,
814
            )
815
            .await?;
9✔
816
        // Validified
817
        test_executor
12✔
818
            .execute_validified::<Form<ParametersValidify>>(
819
                Method::POST,
3✔
820
                extra_form::route::EXTRA_FORM_VALIDIFED,
821
            )
822
            .await?;
9✔
823
        // ValidifiedByRef
824
        test_executor
12✔
825
            .execute::<Form<ParametersValidify>>(
826
                Method::POST,
3✔
827
                extra_form::route::EXTRA_FORM_VALIDIFED_BY_REF,
828
            )
829
            .await?;
9✔
830
    }
831

832
    #[cfg(feature = "extra_protobuf")]
833
    {
834
        use axum_extra::protobuf::Protobuf;
835
        // Validated
836
        test_executor
12✔
837
            .execute::<Protobuf<ParametersValidify>>(
838
                Method::POST,
3✔
839
                extra_protobuf::route::EXTRA_PROTOBUF,
840
            )
841
            .await?;
9✔
842
        // Modified
843
        test_executor
12✔
844
            .execute_modified::<Protobuf<ParametersValidify>>(
845
                Method::POST,
3✔
846
                extra_protobuf::route::EXTRA_PROTOBUF_MODIFIED,
847
            )
848
            .await?;
9✔
849
        // ValidifiedByRef
850
        test_executor
12✔
851
            .execute::<Protobuf<ParametersValidify>>(
852
                Method::POST,
3✔
853
                extra_protobuf::route::EXTRA_PROTOBUF_VALIDIFIED_BY_REF,
854
            )
855
            .await?;
9✔
856
    }
857

858
    #[cfg(feature = "yaml")]
859
    {
860
        use axum_serde::Yaml;
861

862
        // Validated
863
        test_executor
12✔
864
            .execute::<Yaml<ParametersValidify>>(Method::POST, yaml::route::YAML)
3✔
865
            .await?;
9✔
866
        // Modified
867
        test_executor
12✔
868
            .execute_modified::<Yaml<ParametersValidify>>(Method::POST, yaml::route::YAML_MODIFIED)
3✔
869
            .await?;
9✔
870
        // Validified
871
        test_executor
12✔
872
            .execute_validified::<Yaml<ParametersValidify>>(
873
                Method::POST,
3✔
874
                yaml::route::YAML_VALIDIFIED,
875
            )
876
            .await?;
9✔
877
        // ValidifiedByRef
878
        test_executor
12✔
879
            .execute::<Yaml<ParametersValidify>>(Method::POST, yaml::route::YAML_VALIDIFIED_BY_REF)
3✔
880
            .await?;
9✔
881
    }
882

883
    #[cfg(feature = "msgpack")]
884
    {
885
        use axum_serde::{MsgPack, MsgPackRaw};
886
        // Validated
887
        test_executor
12✔
888
            .execute::<MsgPack<ParametersValidify>>(Method::POST, msgpack::route::MSGPACK)
3✔
889
            .await?;
9✔
890
        // Modified
891
        test_executor
12✔
892
            .execute_modified::<MsgPack<ParametersValidify>>(
893
                Method::POST,
3✔
894
                msgpack::route::MSGPACK_MODIFIED,
895
            )
896
            .await?;
9✔
897
        // Validified
898
        test_executor
12✔
899
            .execute_validified::<MsgPack<ParametersValidify>>(
900
                Method::POST,
3✔
901
                msgpack::route::MSGPACK_VALIDIFIED,
902
            )
903
            .await?;
9✔
904
        // ValidifiedByRef
905
        test_executor
12✔
906
            .execute::<MsgPack<ParametersValidify>>(
907
                Method::POST,
3✔
908
                msgpack::route::MSGPACK_VALIDIFIED_BY_REF,
909
            )
910
            .await?;
9✔
911

912
        //
913
        test_executor
12✔
914
            .execute::<MsgPackRaw<ParametersValidify>>(Method::POST, msgpack::route::MSGPACK_RAW)
3✔
915
            .await?;
9✔
916
        //
917
        test_executor
12✔
918
            .execute_modified::<MsgPackRaw<ParametersValidify>>(
919
                Method::POST,
3✔
920
                msgpack::route::MSGPACK_RAW_MODIFIED,
921
            )
922
            .await?;
9✔
923
        //
924
        test_executor
12✔
925
            .execute_validified::<MsgPackRaw<ParametersValidify>>(
926
                Method::POST,
3✔
927
                msgpack::route::MSGPACK_RAW_VALIDIFIED,
928
            )
929
            .await?;
9✔
930
        //
931
        test_executor
12✔
932
            .execute::<MsgPackRaw<ParametersValidify>>(
933
                Method::POST,
3✔
934
                msgpack::route::MSGPACK_RAW_VALIDIFIED_BY_REF,
935
            )
936
            .await?;
9✔
937
    }
938

939
    #[cfg(feature = "xml")]
940
    {
941
        use axum_serde::Xml;
942

943
        // Validated
944
        test_executor
12✔
945
            .execute::<Xml<ParametersValidify>>(Method::POST, xml::route::XML)
3✔
946
            .await?;
9✔
947
        // Modified
948
        test_executor
12✔
949
            .execute_modified::<Xml<ParametersValidify>>(Method::POST, xml::route::XML_MODIFIED)
3✔
950
            .await?;
9✔
951
        // Validified
952
        test_executor
12✔
953
            .execute_validified::<Xml<ParametersValidify>>(Method::POST, xml::route::XML_VALIDIFIED)
3✔
954
            .await?;
9✔
955
        // ValidifiedByRef
956
        test_executor
12✔
957
            .execute::<Xml<ParametersValidify>>(Method::POST, xml::route::XML_VALIDIFIED_BY_REF)
3✔
958
            .await?;
9✔
959
    }
960

961
    #[cfg(feature = "toml")]
962
    {
963
        use axum_serde::Toml;
964

965
        // Validated
966
        test_executor
12✔
967
            .execute::<Toml<ParametersValidify>>(Method::POST, toml::route::TOML)
3✔
968
            .await?;
9✔
969
        // Modified
970
        test_executor
12✔
971
            .execute_modified::<Toml<ParametersValidify>>(Method::POST, toml::route::TOML_MODIFIED)
3✔
972
            .await?;
9✔
973
        // Validified
974
        test_executor
12✔
975
            .execute_validified::<Toml<ParametersValidify>>(
976
                Method::POST,
3✔
977
                toml::route::TOML_VALIDIFIED,
978
            )
979
            .await?;
9✔
980
        // ValidifiedByRef
981
        test_executor
12✔
982
            .execute::<Toml<ParametersValidify>>(Method::POST, toml::route::TOML_VALIDIFIED_BY_REF)
3✔
983
            .await?;
9✔
984
    }
985

986
    Ok(())
3✔
987
}
988

989
#[derive(Debug, Clone)]
990
pub struct TestExecutor {
991
    client: reqwest::Client,
992
    server_url: Url,
993
}
994

995
impl From<Url> for TestExecutor {
996
    fn from(server_url: Url) -> Self {
3✔
997
        Self {
998
            client: Default::default(),
3✔
999
            server_url,
1000
        }
1001
    }
1002
}
1003

1004
impl TestExecutor {
1005
    /// Execute all tests
1006
    pub async fn execute<T: ValidTest>(&self, method: Method, route: &str) -> anyhow::Result<()> {
270✔
1007
        self.do_execute::<T>(
108✔
1008
            method,
×
1009
            route,
×
1010
            StatusCode::OK,
×
1011
            T::ERROR_STATUS_CODE,
×
1012
            T::INVALID_STATUS_CODE,
×
1013
            true,
1014
        )
1015
        .await
162✔
1016
    }
1017

1018
    /// Execute all tests for `Modified` without validation
1019
    pub async fn execute_modified<T: ValidTest>(
51✔
1020
        &self,
1021
        method: Method,
1022
        route: &str,
1023
    ) -> anyhow::Result<()> {
1024
        self.do_execute::<T>(
102✔
1025
            method,
×
1026
            route,
×
1027
            StatusCode::OK,
×
1028
            T::ERROR_STATUS_CODE,
×
1029
            StatusCode::OK,
×
1030
            false,
1031
        )
1032
        .await
153✔
1033
    }
1034

1035
    /// Execute all tests for `Modified` without validation
1036
    pub async fn execute_validified<T: ValidTest>(
30✔
1037
        &self,
1038
        method: Method,
1039
        route: &str,
1040
    ) -> anyhow::Result<()> {
1041
        self.do_execute::<T>(
60✔
1042
            method,
×
1043
            route,
×
1044
            StatusCode::OK,
×
1045
            T::INVALID_STATUS_CODE,
×
1046
            T::INVALID_STATUS_CODE,
×
1047
            false,
1048
        )
1049
        .await
90✔
1050
    }
1051

1052
    async fn do_execute<T: ValidTest>(
57✔
1053
        &self,
1054
        method: Method,
1055
        route: &str,
1056
        expected_valid_status: StatusCode,
1057
        expected_error_status: StatusCode,
1058
        expected_invalid_status: StatusCode,
1059
        should_check_json: bool,
1060
    ) -> anyhow::Result<()> {
1061
        let url = {
×
1062
            let mut url_builder = self.server_url.clone();
57✔
1063
            url_builder.set_path(route);
57✔
1064
            url_builder
57✔
1065
        };
1066

1067
        let type_name = type_name::<T>();
114✔
1068

1069
        let valid_builder = self.client.request(method.clone(), url.clone());
114✔
1070
        let valid_response = T::set_valid_request(valid_builder).send().await?;
171✔
1071
        assert_eq!(
114✔
1072
            valid_response.status().as_u16(),
114✔
1073
            expected_valid_status.as_u16(),
57✔
1074
            "Validified '{}' test failed: {}.",
1075
            type_name,
×
1076
            valid_response.text().await?
×
1077
        );
1078

1079
        let error_builder = self.client.request(method.clone(), url.clone());
114✔
1080
        let error_response = T::set_error_request(error_builder).send().await?;
171✔
1081
        assert_eq!(
114✔
1082
            error_response.status().as_u16(),
114✔
1083
            expected_error_status.as_u16(),
57✔
1084
            "Error '{}' test failed: {}.",
1085
            type_name,
×
1086
            error_response.text().await?
×
1087
        );
1088

1089
        let invalid_builder = self.client.request(method, url);
57✔
1090
        let invalid_response = T::set_invalid_request(invalid_builder).send().await?;
171✔
1091
        assert_eq!(
114✔
1092
            invalid_response.status().as_u16(),
114✔
1093
            expected_invalid_status.as_u16(),
57✔
1094
            "Invalid '{}' test failed: {}.",
1095
            type_name,
×
1096
            invalid_response.text().await?
×
1097
        );
1098
        if should_check_json {
38✔
1099
            #[cfg(feature = "into_json")]
×
1100
            if T::JSON_SERIALIZABLE {
36✔
1101
                check_json(type_name, invalid_response).await;
32✔
1102
            }
1103
        }
1104

1105
        println!("All '{}' tests passed.", type_name);
114✔
1106
        Ok(())
57✔
1107
    }
1108

1109
    pub fn client(&self) -> &reqwest::Client {
3✔
1110
        &self.client
3✔
1111
    }
1112
}
1113

1114
/// Check if the response is a json response
1115
#[cfg(feature = "into_json")]
1116
pub async fn check_json(type_name: &'static str, response: reqwest::Response) {
12✔
1117
    assert_eq!(
4✔
1118
        response.headers()[reqwest::header::CONTENT_TYPE],
4✔
1119
        reqwest::header::HeaderValue::from_static(mime::APPLICATION_JSON.as_ref()),
2✔
1120
        "'{}' rejection into json test failed",
1121
        type_name
1122
    );
1123
    assert!(response.json::<serde_json::Value>().await.is_ok());
2✔
1124
}
1125

1126
mod route {
1127
    pub const PATH: &str = "/path/:v0/:v1";
1128
    pub const PATH_MODIFIED: &str = "/path_modified/:v0/:v1";
1129
    pub const PATH_VALIDIFIED: &str = "/path_validified/:v0/:v1";
1130
    pub const PATH_VALIDIFIED_BY_REF: &str = "/path_validified_by_ref/:v0/:v1";
1131
    pub const QUERY: &str = "/query";
1132
    pub const QUERY_MODIFIED: &str = "/query_modified/:v0/:v1";
1133

1134
    pub const QUERY_VALIDIFIED: &str = "/query_validified/:v0/:v1";
1135
    pub const QUERY_VALIDIFIED_BY_REF: &str = "/query_validified_by_ref/:v0/:v1";
1136
    pub const FORM: &str = "/form";
1137
    pub const FORM_MODIFIED: &str = "/form_modified/:v0/:v1";
1138
    pub const FORM_VALIDIFIED: &str = "/form_validified/:v0/:v1";
1139
    pub const FORM_VALIDIFIED_BY_REF: &str = "/form_validified_by_ref/:v0/:v1";
1140
    pub const JSON: &str = "/json";
1141
    pub const JSON_MODIFIED: &str = "/json_modified/:v0/:v1";
1142
    pub const JSON_VALIDIFIED: &str = "/json_validified/:v0/:v1";
1143
    pub const JSON_VALIDIFIED_BY_REF: &str = "/json_validified_by_ref/:v0/:v1";
1144
}
1145

1146
async fn extract_path(
3✔
1147
    Validated(Path(parameters)): Validated<Path<ParametersValidify>>,
1148
) -> StatusCode {
1149
    check_validated(&parameters)
3✔
1150
}
1151

1152
async fn extract_path_modified(
3✔
1153
    Modified(Path(parameters)): Modified<Path<ParametersValidify>>,
1154
) -> StatusCode {
1155
    check_modified(&parameters)
3✔
1156
}
1157

1158
async fn extract_path_validified(
3✔
1159
    Validified(Path(parameters)): Validified<Path<ParametersValidify>>,
1160
) -> StatusCode {
1161
    check_validified(&parameters)
3✔
1162
}
1163

1164
async fn extract_path_validified_by_ref(
3✔
1165
    ValidifiedByRef(Path(parameters)): ValidifiedByRef<Path<ParametersValidify>>,
1166
) -> StatusCode {
1167
    check_validified(&parameters)
3✔
1168
}
1169

1170
async fn extract_query(
3✔
1171
    Validated(Query(parameters)): Validated<Query<ParametersValidify>>,
1172
) -> StatusCode {
1173
    check_validated(&parameters)
3✔
1174
}
1175

1176
async fn extract_query_modified(
3✔
1177
    Modified(Query(parameters)): Modified<Query<ParametersValidify>>,
1178
) -> StatusCode {
1179
    check_modified(&parameters)
3✔
1180
}
1181

1182
async fn extract_query_validified(
3✔
1183
    Validified(Query(parameters)): Validified<Query<ParametersValidify>>,
1184
) -> StatusCode {
1185
    check_validified(&parameters)
3✔
1186
}
1187

1188
async fn extract_query_validified_by_ref(
3✔
1189
    ValidifiedByRef(Query(parameters)): ValidifiedByRef<Query<ParametersValidify>>,
1190
) -> StatusCode {
1191
    check_validified(&parameters)
3✔
1192
}
1193

1194
async fn extract_form(
3✔
1195
    Validated(Form(parameters)): Validated<Form<ParametersValidify>>,
1196
) -> StatusCode {
1197
    check_validated(&parameters)
3✔
1198
}
1199

1200
async fn extract_form_modified(
3✔
1201
    Modified(Form(parameters)): Modified<Form<ParametersValidify>>,
1202
) -> StatusCode {
1203
    check_modified(&parameters)
3✔
1204
}
1205

1206
async fn extract_form_validified(
3✔
1207
    Validified(Form(parameters)): Validified<Form<ParametersValidify>>,
1208
) -> StatusCode {
1209
    check_validified(&parameters)
3✔
1210
}
1211

1212
async fn extract_form_validified_by_ref(
3✔
1213
    ValidifiedByRef(Form(parameters)): ValidifiedByRef<Form<ParametersValidify>>,
1214
) -> StatusCode {
1215
    check_validified(&parameters)
3✔
1216
}
1217

1218
async fn extract_json(
3✔
1219
    Validated(Json(parameters)): Validated<Json<ParametersValidify>>,
1220
) -> StatusCode {
1221
    check_validated(&parameters)
3✔
1222
}
1223

1224
async fn extract_json_modified(
3✔
1225
    Modified(Json(parameters)): Modified<Json<ParametersValidify>>,
1226
) -> StatusCode {
1227
    check_modified(&parameters)
3✔
1228
}
1229

1230
async fn extract_json_validified(
3✔
1231
    Validified(Json(parameters)): Validified<Json<ParametersValidify>>,
1232
) -> StatusCode {
1233
    check_validified(&parameters)
3✔
1234
}
1235

1236
async fn extract_json_validified_by_ref(
3✔
1237
    ValidifiedByRef(Json(parameters)): ValidifiedByRef<Json<ParametersValidify>>,
1238
) -> StatusCode {
1239
    check_validified(&parameters)
3✔
1240
}
1241

1242
fn check_validated<V: Validate>(validate: &V) -> StatusCode {
9✔
1243
    // The `Validified` extractor has validated the `parameters` once,
1244
    // it should have returned `400 BAD REQUEST` if the `parameters` were invalid,
1245
    // Let's validate them again to check if the `Validated` extractor works well.
1246
    // If it works properly, this function will never return `500 INTERNAL SERVER ERROR`
1247
    match validate.validate() {
9✔
1248
        Ok(_) => StatusCode::OK,
9✔
1249
        Err(e) => {
×
1250
            eprintln!("Data is unvalidated: {e}");
×
1251
            StatusCode::INTERNAL_SERVER_ERROR
×
1252
        }
1253
    }
1254
}
1255

1256
fn check_modified<M: IsModified>(modify: &M) -> StatusCode {
9✔
1257
    if modify.modified() {
9✔
1258
        StatusCode::OK
9✔
1259
    } else {
1260
        StatusCode::INTERNAL_SERVER_ERROR
×
1261
    }
1262
}
1263

1264
fn check_validified<D: IsModified + Validate>(data: &D) -> StatusCode {
6✔
1265
    let status = check_modified(data);
6✔
1266
    if status != StatusCode::OK {
6✔
1267
        return status;
×
1268
    }
1269

1270
    check_validated(data)
6✔
1271
}
1272

1273
#[cfg(feature = "typed_header")]
1274
mod typed_header {
1275

1276
    pub(crate) mod route {
1277
        pub const TYPED_HEADER: &str = "/typed_header";
1278
        pub const TYPED_HEADER_MODIFIED: &str = "/typed_header_modified";
1279
        pub const TYPED_HEADER_VALIDIFIED_BY_REF: &str = "/typed_header_validified_be_ref";
1280
    }
1281

1282
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1283
    use crate::{Modified, Validated, ValidifiedByRef};
1284
    use axum::http::StatusCode;
1285
    use axum_extra::headers::{Error, Header, HeaderName, HeaderValue};
1286
    use axum_extra::typed_header::TypedHeader;
1287

1288
    pub static AXUM_VALID_PARAMETERS: HeaderName = HeaderName::from_static("axum-valid-parameters");
1289

1290
    pub(super) async fn extract_typed_header(
3✔
1291
        Validated(TypedHeader(parameters)): Validated<TypedHeader<ParametersValidify>>,
1292
    ) -> StatusCode {
1293
        check_validated(&parameters)
3✔
1294
    }
1295

1296
    pub(super) async fn extract_typed_header_modified(
3✔
1297
        Modified(TypedHeader(parameters)): Modified<TypedHeader<ParametersValidify>>,
1298
    ) -> StatusCode {
1299
        check_modified(&parameters)
3✔
1300
    }
1301

1302
    pub(super) async fn extract_typed_header_validified_by_ref(
3✔
1303
        ValidifiedByRef(TypedHeader(parameters)): ValidifiedByRef<TypedHeader<ParametersValidify>>,
1304
    ) -> StatusCode {
1305
        check_validified(&parameters)
3✔
1306
    }
1307

1308
    impl Header for ParametersValidify {
1309
        fn name() -> &'static HeaderName {
1310
            &AXUM_VALID_PARAMETERS
1311
        }
1312

1313
        fn decode<'i, I>(values: &mut I) -> Result<Self, Error>
6✔
1314
        where
1315
            Self: Sized,
1316
            I: Iterator<Item = &'i HeaderValue>,
1317
        {
1318
            let value = values.next().ok_or_else(Error::invalid)?;
9✔
1319
            let src = std::str::from_utf8(value.as_bytes()).map_err(|_| Error::invalid())?;
12✔
1320
            let split = src.split(',').collect::<Vec<_>>();
6✔
1321
            match split.as_slice() {
6✔
1322
                [v0, v1] => Ok(ParametersValidify {
18✔
1323
                    v0: v0.parse().map_err(|_| Error::invalid())?,
18✔
1324
                    v1: v1.to_string(),
6✔
1325
                }),
1326
                _ => Err(Error::invalid()),
×
1327
            }
1328
        }
1329

1330
        fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
3✔
1331
            let v0 = self.v0.to_string();
3✔
1332
            let mut vec = Vec::with_capacity(v0.len() + 1 + self.v1.len());
6✔
1333
            vec.extend_from_slice(v0.as_bytes());
6✔
1334
            vec.push(b',');
3✔
1335
            vec.extend_from_slice(self.v1.as_bytes());
3✔
1336
            let value = HeaderValue::from_bytes(&vec).expect("Failed to build header");
3✔
1337
            values.extend(::std::iter::once(value));
3✔
1338
        }
1339
    }
1340

1341
    #[test]
1342
    fn parameter_is_header() -> anyhow::Result<()> {
1343
        let parameter = ParametersValidify {
1344
            v0: 123456,
1345
            v1: "111111".to_string(),
1346
        };
1347
        let mut vec = Vec::new();
1348
        parameter.encode(&mut vec);
1349
        let mut iter = vec.iter();
1350
        assert_eq!(parameter, ParametersValidify::decode(&mut iter)?);
1351
        Ok(())
1352
    }
1353
}
1354

1355
#[cfg(feature = "typed_multipart")]
1356
mod typed_multipart {
1357
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1358
    use crate::{Modified, Validated, ValidifiedByRef};
1359
    use axum::http::StatusCode;
1360
    use axum_typed_multipart::{BaseMultipart, TypedMultipart, TypedMultipartError};
1361

1362
    pub mod route {
1363
        pub const TYPED_MULTIPART: &str = "/typed_multipart";
1364
        pub const TYPED_MULTIPART_MODIFIED: &str = "/typed_multipart_modified";
1365
        pub const TYPED_MULTIPART_VALIDIFIED_BY_REF: &str = "/typed_multipart_validified_by_ref";
1366

1367
        pub const BASE_MULTIPART: &str = "/base_multipart";
1368
        pub const BASE_MULTIPART_MODIFIED: &str = "/base_multipart_modified";
1369
        pub const BASE_MULTIPART_VALIDIFIED_BY_REF: &str = "/base_multipart_validified_by_ref";
1370
    }
1371

1372
    impl From<&ParametersValidify> for reqwest::multipart::Form {
1373
        fn from(value: &ParametersValidify) -> Self {
3✔
1374
            reqwest::multipart::Form::new()
9✔
1375
                .text("v0", value.v0.to_string())
6✔
1376
                .text("v1", value.v1.clone())
6✔
1377
        }
1378
    }
1379

1380
    pub(super) async fn extract_typed_multipart(
3✔
1381
        Validated(TypedMultipart(parameters)): Validated<TypedMultipart<ParametersValidify>>,
1382
    ) -> StatusCode {
1383
        check_validated(&parameters)
3✔
1384
    }
1385

1386
    pub(super) async fn extract_typed_multipart_modified(
3✔
1387
        Modified(TypedMultipart(parameters)): Modified<TypedMultipart<ParametersValidify>>,
1388
    ) -> StatusCode {
1389
        check_modified(&parameters)
3✔
1390
    }
1391

1392
    pub(super) async fn extract_typed_multipart_validified_by_ref(
3✔
1393
        ValidifiedByRef(TypedMultipart(parameters)): ValidifiedByRef<
1394
            TypedMultipart<ParametersValidify>,
1395
        >,
1396
    ) -> StatusCode {
1397
        check_validified(&parameters)
3✔
1398
    }
1399

1400
    pub(super) async fn extract_base_multipart(
3✔
1401
        Validated(BaseMultipart { data, .. }): Validated<
1402
            BaseMultipart<ParametersValidify, TypedMultipartError>,
1403
        >,
1404
    ) -> StatusCode {
1405
        check_validated(&data)
3✔
1406
    }
1407

1408
    pub(super) async fn extract_base_multipart_modified(
3✔
1409
        Modified(BaseMultipart { data, .. }): Modified<
1410
            BaseMultipart<ParametersValidify, TypedMultipartError>,
1411
        >,
1412
    ) -> StatusCode {
1413
        check_modified(&data)
3✔
1414
    }
1415

1416
    pub(super) async fn extract_base_multipart_validified_by_ref(
3✔
1417
        ValidifiedByRef(BaseMultipart { data, .. }): ValidifiedByRef<
1418
            BaseMultipart<ParametersValidify, TypedMultipartError>,
1419
        >,
1420
    ) -> StatusCode {
1421
        check_validified(&data)
3✔
1422
    }
1423
}
1424

1425
#[cfg(feature = "extra")]
1426
mod extra {
1427
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1428
    use crate::tests::{Rejection, ValidTest, ValidTestParameter};
1429
    use crate::{HasModify, Modified, Validated, ValidifiedByRef, ValidifyRejection};
1430
    use axum::extract::FromRequestParts;
1431
    use axum::http::request::Parts;
1432
    use axum::http::StatusCode;
1433
    use axum::response::{IntoResponse, Response};
1434
    use axum_extra::extract::{Cached, WithRejection};
1435
    use reqwest::RequestBuilder;
1436

1437
    pub mod route {
1438
        pub const CACHED: &str = "/cached";
1439
        pub const CACHED_MODIFIED: &str = "/cached_modified";
1440
        pub const CACHED_VALIDIFIED_BY_REF: &str = "/cached_validified_by_ref";
1441
        pub const WITH_REJECTION: &str = "/with_rejection";
1442
        pub const WITH_REJECTION_MODIFIED: &str = "/with_rejection_modified";
1443
        pub const WITH_REJECTION_VALIDIFIED_BY_REF: &str = "/with_rejection_validified_by_ref";
1444
        pub const WITH_REJECTION_VALIDIFY: &str = "/with_rejection_validify";
1445
        pub const WITH_REJECTION_VALIDIFY_MODIFIED: &str = "/with_rejection_validify_modified";
1446
        pub const WITH_REJECTION_VALIDIFY_VALIDIFIED_BY_REF: &str =
1447
            "/with_rejection_validify_validified_by_ref";
1448
    }
1449
    pub const PARAMETERS_HEADER: &str = "parameters-header";
1450
    pub const CACHED_REJECTION_STATUS: StatusCode = StatusCode::FORBIDDEN;
1451

1452
    //  1.2. Define you own `Rejection` type and implement `IntoResponse` for it.
1453
    pub enum ParametersRejection {
1454
        Null,
1455
        InvalidJson(serde_json::error::Error),
1456
    }
1457

1458
    impl IntoResponse for ParametersRejection {
1459
        fn into_response(self) -> Response {
3✔
1460
            match self {
3✔
1461
                ParametersRejection::Null => {
1462
                    (CACHED_REJECTION_STATUS, "My-Data header is missing").into_response()
×
1463
                }
1464
                ParametersRejection::InvalidJson(e) => (
6✔
1465
                    CACHED_REJECTION_STATUS,
1466
                    format!("My-Data is not valid json string: {e}"),
3✔
1467
                )
1468
                    .into_response(),
1469
            }
1470
        }
1471
    }
1472

1473
    //  1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
1474
    #[axum::async_trait]
1475
    impl<S> FromRequestParts<S> for ParametersValidify
1476
    where
1477
        S: Send + Sync,
1478
    {
1479
        type Rejection = ParametersRejection;
1480

1481
        async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
15✔
1482
            let Some(value) = parts.headers.get(PARAMETERS_HEADER) else {
3✔
1483
                return Err(ParametersRejection::Null);
×
1484
            };
1485

1486
            serde_json::from_slice(value.as_bytes()).map_err(ParametersRejection::InvalidJson)
6✔
1487
        }
1488
    }
1489

1490
    impl ValidTest for ParametersValidify {
1491
        const ERROR_STATUS_CODE: StatusCode = CACHED_REJECTION_STATUS;
1492

1493
        fn set_valid_request(builder: RequestBuilder) -> RequestBuilder {
3✔
1494
            builder.header(
6✔
1495
                PARAMETERS_HEADER,
1496
                serde_json::to_string(ParametersValidify::valid())
6✔
1497
                    .expect("Failed to serialize parameters"),
1498
            )
1499
        }
1500

1501
        fn set_error_request(builder: RequestBuilder) -> RequestBuilder {
3✔
1502
            builder.header(
6✔
1503
                PARAMETERS_HEADER,
1504
                serde_json::to_string(ParametersValidify::error())
6✔
1505
                    .expect("Failed to serialize parameters"),
1506
            )
1507
        }
1508

1509
        fn set_invalid_request(builder: RequestBuilder) -> RequestBuilder {
3✔
1510
            builder.header(
6✔
1511
                PARAMETERS_HEADER,
1512
                serde_json::to_string(ParametersValidify::invalid())
6✔
1513
                    .expect("Failed to serialize parameters"),
1514
            )
1515
        }
1516
    }
1517

1518
    impl HasModify for ParametersValidify {
1519
        type Modify = Self;
1520

1521
        fn get_modify(&mut self) -> &mut Self::Modify {
3✔
1522
            self
1523
        }
1524
    }
1525

1526
    pub struct ValidifyWithRejectionRejection {
1527
        inner: ParametersRejection,
1528
    }
1529

1530
    impl Rejection for ValidifyWithRejectionRejection {
1531
        const STATUS_CODE: StatusCode = StatusCode::CONFLICT;
1532
    }
1533

1534
    impl IntoResponse for ValidifyWithRejectionRejection {
1535
        fn into_response(self) -> Response {
3✔
1536
            let mut response = self.inner.into_response();
3✔
1537
            *response.status_mut() = Self::STATUS_CODE;
6✔
1538
            response
3✔
1539
        }
1540
    }
1541

1542
    // satisfy the `WithRejection`'s extractor trait bound
1543
    // R: From<E::Rejection> + IntoResponse
1544
    impl From<ParametersRejection> for ValidifyWithRejectionRejection {
1545
        fn from(inner: ParametersRejection) -> Self {
3✔
1546
            Self { inner }
1547
        }
1548
    }
1549

1550
    pub async fn extract_cached(
3✔
1551
        Validated(Cached(parameters)): Validated<Cached<ParametersValidify>>,
1552
    ) -> StatusCode {
1553
        check_validated(&parameters)
3✔
1554
    }
1555

1556
    pub async fn extract_cached_modified(
3✔
1557
        Modified(Cached(parameters)): Modified<Cached<ParametersValidify>>,
1558
    ) -> StatusCode {
1559
        check_modified(&parameters)
3✔
1560
    }
1561

1562
    pub async fn extract_cached_validified_by_ref(
3✔
1563
        ValidifiedByRef(Cached(parameters)): ValidifiedByRef<Cached<ParametersValidify>>,
1564
    ) -> StatusCode {
1565
        check_validified(&parameters)
3✔
1566
    }
1567

1568
    pub async fn extract_with_rejection(
3✔
1569
        Validated(WithRejection(parameters, _)): Validated<
1570
            WithRejection<ParametersValidify, ValidifyWithRejectionRejection>,
1571
        >,
1572
    ) -> StatusCode {
1573
        check_validated(&parameters)
3✔
1574
    }
1575

1576
    pub async fn extract_with_rejection_modified(
3✔
1577
        Modified(WithRejection(parameters, _)): Modified<
1578
            WithRejection<ParametersValidify, ValidifyWithRejectionRejection>,
1579
        >,
1580
    ) -> StatusCode {
1581
        check_modified(&parameters)
3✔
1582
    }
1583

1584
    pub async fn extract_with_rejection_validified_by_ref(
3✔
1585
        ValidifiedByRef(WithRejection(parameters, _)): ValidifiedByRef<
1586
            WithRejection<ParametersValidify, ValidifyWithRejectionRejection>,
1587
        >,
1588
    ) -> StatusCode {
1589
        check_validified(&parameters)
3✔
1590
    }
1591

1592
    pub struct WithRejectionValidifyRejection<E> {
1593
        inner: ValidifyRejection<E>,
1594
    }
1595

1596
    impl<E> From<ValidifyRejection<E>> for WithRejectionValidifyRejection<E> {
1597
        fn from(inner: ValidifyRejection<E>) -> Self {
3✔
1598
            Self { inner }
1599
        }
1600
    }
1601

1602
    impl<E: IntoResponse> IntoResponse for WithRejectionValidifyRejection<E> {
1603
        fn into_response(self) -> Response {
3✔
1604
            let mut res = self.inner.into_response();
3✔
1605
            *res.status_mut() = StatusCode::IM_A_TEAPOT;
6✔
1606
            res
3✔
1607
        }
1608
    }
1609

1610
    pub async fn extract_with_rejection_validifiy(
3✔
1611
        WithRejection(Validated(parameters), _): WithRejection<
1612
            Validated<ParametersValidify>,
1613
            WithRejectionValidifyRejection<ParametersRejection>,
1614
        >,
1615
    ) -> StatusCode {
1616
        check_validated(&parameters)
3✔
1617
    }
1618

1619
    pub async fn extract_with_rejection_validifiy_modified(
3✔
1620
        WithRejection(Modified(parameters), _): WithRejection<
1621
            Modified<ParametersValidify>,
1622
            ValidifyWithRejectionRejection,
1623
        >,
1624
    ) -> StatusCode {
1625
        check_modified(&parameters)
3✔
1626
    }
1627

1628
    pub async fn extract_with_rejection_validifiy_validified_by_ref(
3✔
1629
        WithRejection(ValidifiedByRef(parameters), _): WithRejection<
1630
            ValidifiedByRef<ParametersValidify>,
1631
            WithRejectionValidifyRejection<ParametersRejection>,
1632
        >,
1633
    ) -> StatusCode {
1634
        check_validified(&parameters)
3✔
1635
    }
1636
}
1637

1638
#[cfg(feature = "extra_typed_path")]
1639
mod extra_typed_path {
1640
    use super::{check_modified, check_validated, check_validified};
1641
    use crate::{HasModify, HasValidate, Modified, Validated, ValidifiedByRef};
1642
    use axum::http::StatusCode;
1643
    use axum_extra::routing::TypedPath;
1644
    use serde::Deserialize;
1645
    use validify::{Validate, Validify};
1646

1647
    pub mod route {
1648
        pub const EXTRA_TYPED_PATH: &str = "/extra_typed_path/:v0/:v1";
1649
        pub const EXTRA_TYPED_PATH_MODIFIED: &str = "/extra_typed_path_modified/:v0/:v1";
1650
        pub const EXTRA_TYPED_PATH_VALIDIFIED_BY_REF: &str =
1651
            "/extra_typed_path_validified_by_ref/:v0/:v1";
1652
    }
1653

1654
    #[derive(Validate, TypedPath, Deserialize)]
1655
    #[typed_path("/extra_typed_path/:v0/:v1")]
1656
    pub struct TypedPathParam {
1657
        #[validate(range(min = 5.0, max = 10.0))]
1658
        v0: i32,
1659
        #[validate(length(min = 1, max = 10))]
1660
        v1: String,
1661
    }
1662

1663
    impl HasValidate for TypedPathParam {
1664
        type Validate = Self;
1665

1666
        fn get_validate(&self) -> &Self::Validate {
3✔
1667
            self
1668
        }
1669
    }
1670

1671
    #[derive(Validify, TypedPath, Deserialize, Clone, PartialEq, Eq)]
1672
    #[typed_path("/extra_typed_path_validified_by_ref/:v0/:v1")]
1673
    pub struct TypedPathParamValidifiedByRef {
1674
        #[validate(range(min = 5.0, max = 10.0))]
1675
        v0: i32,
1676
        #[modify(lowercase)]
1677
        #[validate(length(min = 1, max = 10))]
1678
        v1: String,
1679
    }
1680

1681
    impl HasValidate for TypedPathParamValidifiedByRef {
1682
        type Validate = Self;
1683

1684
        fn get_validate(&self) -> &Self::Validate {
3✔
1685
            self
1686
        }
1687
    }
1688

1689
    impl HasModify for TypedPathParamValidifiedByRef {
1690
        type Modify = Self;
1691

1692
        fn get_modify(&mut self) -> &mut Self::Modify {
3✔
1693
            self
1694
        }
1695
    }
1696

1697
    #[derive(Validify, TypedPath, Deserialize, Clone, PartialEq, Eq)]
1698
    #[typed_path("/extra_typed_path_modified/:v0/:v1")]
1699
    pub struct TypedPathParamModified {
1700
        #[validate(range(min = 5.0, max = 10.0))]
1701
        v0: i32,
1702
        #[modify(lowercase)]
1703
        #[validate(length(min = 1, max = 10))]
1704
        v1: String,
1705
    }
1706

1707
    impl HasModify for TypedPathParamModified {
1708
        type Modify = Self;
1709

1710
        fn get_modify(&mut self) -> &mut Self::Modify {
3✔
1711
            self
1712
        }
1713
    }
1714

1715
    pub async fn extract_extra_typed_path(
3✔
1716
        Validated(param): Validated<TypedPathParam>,
1717
    ) -> StatusCode {
1718
        check_validated(&param)
3✔
1719
    }
1720

1721
    pub async fn extract_extra_typed_path_modified(
3✔
1722
        Modified(param): Modified<TypedPathParamModified>,
1723
    ) -> StatusCode {
1724
        check_modified(&param)
3✔
1725
    }
1726

1727
    pub async fn extract_extra_typed_path_validified_by_ref(
3✔
1728
        ValidifiedByRef(param): ValidifiedByRef<TypedPathParamValidifiedByRef>,
1729
    ) -> StatusCode {
1730
        check_validified(&param)
3✔
1731
    }
1732
}
1733

1734
#[cfg(feature = "extra_query")]
1735
mod extra_query {
1736
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1737
    use crate::{Modified, Validated, Validified, ValidifiedByRef};
1738
    use axum::http::StatusCode;
1739
    use axum_extra::extract::Query;
1740

1741
    pub mod route {
1742
        pub const EXTRA_QUERY: &str = "/extra_query";
1743
        pub const EXTRA_QUERY_MODIFIED: &str = "/extra_query_modified";
1744
        pub const EXTRA_QUERY_VALIDIFIED: &str = "/extra_query_validified";
1745
        pub const EXTRA_QUERY_VALIDIFIED_BY_REF: &str = "/extra_query_validified_by_ref";
1746
    }
1747

1748
    pub async fn extract_extra_query(
3✔
1749
        Validated(Query(parameters)): Validated<Query<ParametersValidify>>,
1750
    ) -> StatusCode {
1751
        check_validated(&parameters)
3✔
1752
    }
1753

1754
    pub async fn extract_extra_query_modified(
3✔
1755
        Modified(Query(parameters)): Modified<Query<ParametersValidify>>,
1756
    ) -> StatusCode {
1757
        check_modified(&parameters)
3✔
1758
    }
1759

1760
    pub async fn extract_extra_query_validified(
3✔
1761
        Validified(Query(parameters)): Validified<Query<ParametersValidify>>,
1762
    ) -> StatusCode {
1763
        check_validified(&parameters)
3✔
1764
    }
1765

1766
    pub async fn extract_extra_query_validified_by_ref(
3✔
1767
        ValidifiedByRef(Query(parameters)): ValidifiedByRef<Query<ParametersValidify>>,
1768
    ) -> StatusCode {
1769
        check_validified(&parameters)
3✔
1770
    }
1771
}
1772

1773
#[cfg(feature = "extra_form")]
1774
mod extra_form {
1775
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1776
    use crate::{Modified, Validated, Validified, ValidifiedByRef};
1777
    use axum::http::StatusCode;
1778
    use axum_extra::extract::Form;
1779

1780
    pub mod route {
1781
        pub const EXTRA_FORM: &str = "/extra_form";
1782
        pub const EXTRA_FORM_MODIFIED: &str = "/extra_form_modified";
1783
        pub const EXTRA_FORM_VALIDIFED: &str = "/extra_form_validifed";
1784
        pub const EXTRA_FORM_VALIDIFED_BY_REF: &str = "/extra_form_validified_by_ref";
1785
    }
1786

1787
    pub async fn extract_extra_form(
3✔
1788
        Validated(Form(parameters)): Validated<Form<ParametersValidify>>,
1789
    ) -> StatusCode {
1790
        check_validated(&parameters)
3✔
1791
    }
1792

1793
    pub async fn extract_extra_form_modified(
3✔
1794
        Modified(Form(parameters)): Modified<Form<ParametersValidify>>,
1795
    ) -> StatusCode {
1796
        check_modified(&parameters)
3✔
1797
    }
1798

1799
    pub async fn extract_extra_form_validifed(
3✔
1800
        Validified(Form(parameters)): Validified<Form<ParametersValidify>>,
1801
    ) -> StatusCode {
1802
        check_validified(&parameters)
3✔
1803
    }
1804

1805
    pub async fn extract_extra_form_validifed_by_ref(
3✔
1806
        ValidifiedByRef(Form(parameters)): ValidifiedByRef<Form<ParametersValidify>>,
1807
    ) -> StatusCode {
1808
        check_validified(&parameters)
3✔
1809
    }
1810
}
1811

1812
#[cfg(feature = "extra_protobuf")]
1813
mod extra_protobuf {
1814
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1815
    use crate::{Modified, Validated, ValidifiedByRef};
1816
    use axum::http::StatusCode;
1817
    use axum_extra::protobuf::Protobuf;
1818

1819
    pub mod route {
1820
        pub const EXTRA_PROTOBUF: &str = "/extra_protobuf";
1821
        pub const EXTRA_PROTOBUF_MODIFIED: &str = "/extra_protobuf_modified";
1822
        pub const EXTRA_PROTOBUF_VALIDIFIED_BY_REF: &str = "/extra_protobuf_validified_by_ref";
1823
    }
1824

1825
    pub async fn extract_extra_protobuf(
3✔
1826
        Validated(Protobuf(parameters)): Validated<Protobuf<ParametersValidify>>,
1827
    ) -> StatusCode {
1828
        check_validated(&parameters)
3✔
1829
    }
1830

1831
    pub async fn extract_extra_protobuf_modified(
3✔
1832
        Modified(Protobuf(parameters)): Modified<Protobuf<ParametersValidify>>,
1833
    ) -> StatusCode {
1834
        check_modified(&parameters)
3✔
1835
    }
1836

1837
    pub async fn extract_extra_protobuf_validified_by_ref(
3✔
1838
        ValidifiedByRef(Protobuf(parameters)): ValidifiedByRef<Protobuf<ParametersValidify>>,
1839
    ) -> StatusCode {
1840
        check_validified(&parameters)
3✔
1841
    }
1842
}
1843

1844
#[cfg(feature = "yaml")]
1845
mod yaml {
1846
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1847
    use crate::{Modified, Validated, Validified, ValidifiedByRef};
1848
    use axum::http::StatusCode;
1849
    use axum_serde::Yaml;
1850

1851
    pub mod route {
1852
        pub const YAML: &str = "/yaml";
1853
        pub const YAML_MODIFIED: &str = "/yaml_modified";
1854
        pub const YAML_VALIDIFIED: &str = "/yaml_validified";
1855
        pub const YAML_VALIDIFIED_BY_REF: &str = "/yaml_validified_by_ref";
1856
    }
1857

1858
    pub async fn extract_yaml(
3✔
1859
        Validated(Yaml(parameters)): Validated<Yaml<ParametersValidify>>,
1860
    ) -> StatusCode {
1861
        check_validated(&parameters)
3✔
1862
    }
1863

1864
    pub async fn extract_yaml_modified(
3✔
1865
        Modified(Yaml(parameters)): Modified<Yaml<ParametersValidify>>,
1866
    ) -> StatusCode {
1867
        check_modified(&parameters)
3✔
1868
    }
1869

1870
    pub async fn extract_yaml_validified(
3✔
1871
        Validified(Yaml(parameters)): Validified<Yaml<ParametersValidify>>,
1872
    ) -> StatusCode {
1873
        check_validified(&parameters)
3✔
1874
    }
1875

1876
    pub async fn extract_yaml_validified_by_ref(
3✔
1877
        ValidifiedByRef(Yaml(parameters)): ValidifiedByRef<Yaml<ParametersValidify>>,
1878
    ) -> StatusCode {
1879
        check_validified(&parameters)
3✔
1880
    }
1881
}
1882

1883
#[cfg(feature = "msgpack")]
1884
mod msgpack {
1885
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1886
    use crate::{Modified, Validated, Validified, ValidifiedByRef};
1887
    use axum::http::StatusCode;
1888
    use axum_serde::{MsgPack, MsgPackRaw};
1889

1890
    pub mod route {
1891
        pub const MSGPACK: &str = "/msgpack";
1892
        pub const MSGPACK_MODIFIED: &str = "/msgpack_modified";
1893
        pub const MSGPACK_VALIDIFIED: &str = "/msgpack_validified";
1894
        pub const MSGPACK_VALIDIFIED_BY_REF: &str = "/msgpack_validified_by_ref";
1895
        pub const MSGPACK_RAW: &str = "/msgpack_raw";
1896
        pub const MSGPACK_RAW_MODIFIED: &str = "/msgpack_raw_modified";
1897
        pub const MSGPACK_RAW_VALIDIFIED: &str = "/msgpack_raw_validified";
1898
        pub const MSGPACK_RAW_VALIDIFIED_BY_REF: &str = "/msgpack_raw_validified_by_ref";
1899
    }
1900

1901
    pub async fn extract_msgpack(
3✔
1902
        Validated(MsgPack(parameters)): Validated<MsgPack<ParametersValidify>>,
1903
    ) -> StatusCode {
1904
        check_validated(&parameters)
3✔
1905
    }
1906

1907
    pub async fn extract_msgpack_modified(
3✔
1908
        Modified(MsgPack(parameters)): Modified<MsgPack<ParametersValidify>>,
1909
    ) -> StatusCode {
1910
        check_modified(&parameters)
3✔
1911
    }
1912

1913
    pub async fn extract_msgpack_validified(
3✔
1914
        Validified(MsgPack(parameters)): Validified<MsgPack<ParametersValidify>>,
1915
    ) -> StatusCode {
1916
        check_validified(&parameters)
3✔
1917
    }
1918

1919
    pub async fn extract_msgpack_validified_by_ref(
3✔
1920
        ValidifiedByRef(MsgPack(parameters)): ValidifiedByRef<MsgPack<ParametersValidify>>,
1921
    ) -> StatusCode {
1922
        check_validified(&parameters)
3✔
1923
    }
1924
    pub async fn extract_msgpack_raw(
3✔
1925
        Validated(MsgPackRaw(parameters)): Validated<MsgPackRaw<ParametersValidify>>,
1926
    ) -> StatusCode {
1927
        check_validated(&parameters)
3✔
1928
    }
1929

1930
    pub async fn extract_msgpack_raw_modified(
3✔
1931
        Modified(MsgPackRaw(parameters)): Modified<MsgPackRaw<ParametersValidify>>,
1932
    ) -> StatusCode {
1933
        check_modified(&parameters)
3✔
1934
    }
1935

1936
    pub async fn extract_msgpack_raw_validified(
3✔
1937
        Validified(MsgPackRaw(parameters)): Validified<MsgPackRaw<ParametersValidify>>,
1938
    ) -> StatusCode {
1939
        check_validified(&parameters)
3✔
1940
    }
1941

1942
    pub async fn extract_msgpack_raw_validified_by_ref(
3✔
1943
        ValidifiedByRef(MsgPackRaw(parameters)): ValidifiedByRef<MsgPackRaw<ParametersValidify>>,
1944
    ) -> StatusCode {
1945
        check_validified(&parameters)
3✔
1946
    }
1947
}
1948

1949
#[cfg(feature = "xml")]
1950
mod xml {
1951
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1952
    use crate::{Modified, Validated, Validified, ValidifiedByRef};
1953
    use axum::http::StatusCode;
1954
    use axum_serde::Xml;
1955

1956
    pub mod route {
1957
        pub const XML: &str = "/xml";
1958
        pub const XML_MODIFIED: &str = "/xml_modified";
1959
        pub const XML_VALIDIFIED: &str = "/xml_validified";
1960
        pub const XML_VALIDIFIED_BY_REF: &str = "/xml_validified_by_ref";
1961
    }
1962

1963
    pub async fn extract_xml(
3✔
1964
        Validated(Xml(parameters)): Validated<Xml<ParametersValidify>>,
1965
    ) -> StatusCode {
1966
        check_validated(&parameters)
3✔
1967
    }
1968

1969
    pub async fn extract_xml_modified(
3✔
1970
        Modified(Xml(parameters)): Modified<Xml<ParametersValidify>>,
1971
    ) -> StatusCode {
1972
        check_modified(&parameters)
3✔
1973
    }
1974

1975
    pub async fn extract_xml_validified(
3✔
1976
        Validified(Xml(parameters)): Validified<Xml<ParametersValidify>>,
1977
    ) -> StatusCode {
1978
        check_validified(&parameters)
3✔
1979
    }
1980

1981
    pub async fn extract_xml_validified_by_ref(
3✔
1982
        ValidifiedByRef(Xml(parameters)): ValidifiedByRef<Xml<ParametersValidify>>,
1983
    ) -> StatusCode {
1984
        check_validified(&parameters)
3✔
1985
    }
1986
}
1987

1988
#[cfg(feature = "toml")]
1989
mod toml {
1990
    use super::{check_modified, check_validated, check_validified, ParametersValidify};
1991
    use crate::{Modified, Validated, Validified, ValidifiedByRef};
1992
    use axum::http::StatusCode;
1993
    use axum_serde::Toml;
1994

1995
    pub mod route {
1996
        pub const TOML: &str = "/toml";
1997
        pub const TOML_MODIFIED: &str = "/toml_modified";
1998
        pub const TOML_VALIDIFIED: &str = "/toml_validified";
1999
        pub const TOML_VALIDIFIED_BY_REF: &str = "/toml_validified_by_ref";
2000
    }
2001

2002
    pub async fn extract_toml(
3✔
2003
        Validated(Toml(parameters)): Validated<Toml<ParametersValidify>>,
2004
    ) -> StatusCode {
2005
        check_validated(&parameters)
3✔
2006
    }
2007

2008
    pub async fn extract_toml_modified(
3✔
2009
        Modified(Toml(parameters)): Modified<Toml<ParametersValidify>>,
2010
    ) -> StatusCode {
2011
        check_modified(&parameters)
3✔
2012
    }
2013

2014
    pub async fn extract_toml_validified(
3✔
2015
        Validified(Toml(parameters)): Validified<Toml<ParametersValidify>>,
2016
    ) -> StatusCode {
2017
        check_validified(&parameters)
3✔
2018
    }
2019

2020
    pub async fn extract_toml_validified_by_ref(
3✔
2021
        ValidifiedByRef(Toml(parameters)): ValidifiedByRef<Toml<ParametersValidify>>,
2022
    ) -> StatusCode {
2023
        check_validified(&parameters)
3✔
2024
    }
2025
}
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