axum_valid/
path.rs

1//! # Support for `Path<T>`
2//!
3//! ## Usage
4//!
5//! 1. Implement `Deserialize` and `Validate` for your data type `T`.
6//! 2. In your handler function, use `Valid<Path<T>>` as some parameter's type.
7//!
8//! ## Example
9//!
10//! ```no_run
11//! #[cfg(feature = "validator")]
12//! mod validator_example {
13//!     use axum::extract::Path;
14//!     use axum::routing::post;
15//!     use axum::Router;
16//!     use axum_valid::Valid;
17//!     use serde::Deserialize;
18//!     use validator::Validate;
19//!
20//!     pub fn router() -> Router {
21//!         Router::new().route("/path", post(handler))
22//!     }
23//!
24//!     async fn handler(Valid(Path(parameter)): Valid<Path<Parameter>>) {
25//!         assert!(parameter.validate().is_ok());
26//!         // Support automatic dereferencing
27//!         println!("v0 = {}, v1 = {}", parameter.v0, parameter.v1);
28//!     }
29//!
30//!     #[derive(Validate, Deserialize)]
31//!     pub struct Parameter {
32//!         #[validate(range(min = 5, max = 10))]
33//!         pub v0: i32,
34//!         #[validate(length(min = 1, max = 10))]
35//!         pub v1: String,
36//!     }
37//! }
38//!
39//! #[cfg(feature = "garde")]
40//! mod garde_example {
41//!     use axum::routing::post;
42//!     use axum::extract::Path;
43//!     use axum::Router;
44//!     use axum_valid::Garde;
45//!     use serde::Deserialize;
46//!     use garde::Validate;
47//!
48//!     pub fn router() -> Router {
49//!         Router::new().route("/path", post(handler))
50//!     }
51//!
52//!     async fn handler(Garde(Path(parameter)): Garde<Path<Parameter>>) {
53//!         assert!(parameter.validate_with(&()).is_ok());
54//!         // Support automatic dereferencing
55//!         println!("v0 = {}, v1 = {}", parameter.v0, parameter.v1);
56//!     }
57//!
58//!     #[derive(Validate, Deserialize)]
59//!     pub struct Parameter {
60//!         #[garde(range(min = 5, max = 10))]
61//!         pub v0: i32,
62//!         #[garde(length(min = 1, max = 10))]
63//!         pub v1: String,
64//!     }
65//! }
66//!
67//! # #[tokio::main]
68//! # async fn main() -> anyhow::Result<()> {
69//! #     use std::net::SocketAddr;
70//! #     use axum::Router;
71//! #     use tokio::net::TcpListener;
72//! #     let router = Router::new();
73//! #     #[cfg(feature = "validator")]
74//! #     let router = router.nest("/validator", validator_example::router());
75//! #     #[cfg(feature = "garde")]
76//! #     let router = router.nest("/garde", garde_example::router());
77//! #     let listener = TcpListener::bind(&SocketAddr::from(([0u8, 0, 0, 0], 0u16))).await?;
78//! #     axum::serve(listener, router.into_make_service())
79//! #         .await?;
80//! #     Ok(())
81//! # }
82//! ```
83
84use crate::HasValidate;
85#[cfg(feature = "validator")]
86use crate::HasValidateArgs;
87use axum::extract::Path;
88#[cfg(feature = "validator")]
89use validator::ValidateArgs;
90
91impl<T> HasValidate for Path<T> {
92    type Validate = T;
93    fn get_validate(&self) -> &T {
94        &self.0
95    }
96}
97
98#[cfg(feature = "validator")]
99impl<'v, T: ValidateArgs<'v>> HasValidateArgs<'v> for Path<T> {
100    type ValidateArgs = T;
101    fn get_validate_args(&self) -> &Self::ValidateArgs {
102        &self.0
103    }
104}
105
106#[cfg(feature = "validify")]
107impl<T: validify::Modify> crate::HasModify for Path<T> {
108    type Modify = T;
109
110    fn get_modify(&mut self) -> &mut Self::Modify {
111        &mut self.0
112    }
113}
114
115#[cfg(feature = "validify")]
116impl<T> crate::PayloadExtractor for Path<T> {
117    type Payload = T;
118
119    fn get_payload(self) -> Self::Payload {
120        self.0
121    }
122}
123
124#[cfg(feature = "validify")]
125impl<T: validify::Validify + validify::ValidifyPayload> crate::HasValidify for Path<T> {
126    type Validify = T;
127    type PayloadExtractor = Path<T::Payload>;
128
129    fn from_validify(v: Self::Validify) -> Self {
130        Path(v)
131    }
132}