Compare commits
11 Commits
20886c16d8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9533608bc | ||
|
|
c603d48313 | ||
|
|
cdec7d9b23 | ||
|
|
73e5ef0876 | ||
|
|
3f0e5aece3 | ||
|
|
0e924e6baf | ||
|
|
99aa6e0054 | ||
|
|
1f2d0419b4 | ||
|
|
2ef8421875 | ||
|
|
1943a472bc | ||
|
|
b76d4ef427 |
40
Cargo.toml
40
Cargo.toml
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "axum-valid"
|
name = "axum-valid"
|
||||||
version = "0.20.0"
|
version = "0.23.0"
|
||||||
description = "Provides validation extractors for your Axum application, allowing you to validate data using validator, garde, validify or all of them."
|
description = "Provides validation extractors for your Axum application, allowing you to validate data using validator, garde, validify or all of them."
|
||||||
authors = ["GengTeng <me@gteng.org>"]
|
authors = ["GengTeng <me@gteng.org>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@@ -25,49 +25,49 @@ edition = "2021"
|
|||||||
features = ["full", "aide"]
|
features = ["full", "aide"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = { version = "0.7.5", default-features = false }
|
axum = { version = "0.8", default-features = false }
|
||||||
garde = { version = "0.20.0", optional = true }
|
garde = { version = "0.22.0", optional = true }
|
||||||
validator = { version = "0.18.1", optional = true }
|
validator = { version = "0.20.0", optional = true }
|
||||||
validify = { version = "1.4.0", optional = true }
|
validify = { version = "2.0.0", optional = true }
|
||||||
|
|
||||||
[dependencies.axum-extra]
|
[dependencies.axum-extra]
|
||||||
version = "0.9.3"
|
version = "0.10"
|
||||||
default-features = false
|
default-features = false
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.axum-serde]
|
[dependencies.axum-serde]
|
||||||
version = "0.6.1"
|
version = "0.8.1"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.axum_typed_multipart]
|
[dependencies.axum_typed_multipart]
|
||||||
version = "0.12.1"
|
version = "0.15.1"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1.0.210"
|
version = "1.0.217"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.aide]
|
[dependencies.aide]
|
||||||
version = "0.13.4"
|
version = "0.14.0"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
anyhow = "1.0.87"
|
anyhow = "1.0.87"
|
||||||
axum = { version = "0.7.5", features = ["macros"] }
|
axum = { version = "0.8", features = ["macros"] }
|
||||||
tokio = { version = "1.34.0", features = ["full"] }
|
tokio = { version = "1.43.0", features = ["full"] }
|
||||||
reqwest = { version = "0.12.3", features = ["json", "multipart"] }
|
reqwest = { version = "0.12.3", features = ["json", "multipart"] }
|
||||||
serde = { version = "1.0.195", features = ["derive"] }
|
serde = { version = "1.0.195", features = ["derive"] }
|
||||||
validator = { version = "0.18.0", features = ["derive"] }
|
validator = { version = "0.20.0", features = ["derive"] }
|
||||||
garde = { version = "0.20.0", features = ["serde", "derive"] }
|
garde = { version = "0.22.0", features = ["serde", "derive"] }
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
serde_yaml = "0.9.27"
|
serde_yaml = "0.9.33"
|
||||||
quick-xml = { version = "0.36.1", features = ["serialize"] }
|
quick-xml = { version = "0.37.1", features = ["serialize"] }
|
||||||
ciborium = { version = "0.2.2" }
|
ciborium = { version = "0.2.2" }
|
||||||
toml = "0.8.8"
|
toml = "0.8.14"
|
||||||
mime = "0.3.17"
|
mime = "0.3.17"
|
||||||
prost = "0.12.3"
|
prost = "0.13.4"
|
||||||
once_cell = "1.18.0"
|
once_cell = "1.20.2"
|
||||||
rmp-serde = "1.1.2"
|
rmp-serde = "1.3.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["basic", "validator"]
|
default = ["basic", "validator"]
|
||||||
|
|||||||
11
src/extra.rs
11
src/extra.rs
@@ -61,7 +61,6 @@
|
|||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[axum::async_trait]
|
|
||||||
//! impl<S> FromRequestParts<S> for Parameter
|
//! impl<S> FromRequestParts<S> for Parameter
|
||||||
//! where
|
//! where
|
||||||
//! S: Send + Sync,
|
//! S: Send + Sync,
|
||||||
@@ -108,7 +107,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[axum::async_trait]
|
//!
|
||||||
//! impl<S> FromRequestParts<S> for Parameter
|
//! impl<S> FromRequestParts<S> for Parameter
|
||||||
//! where
|
//! where
|
||||||
//! S: Send + Sync,
|
//! S: Send + Sync,
|
||||||
@@ -189,7 +188,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[axum::async_trait]
|
//!
|
||||||
//! impl<S> FromRequestParts<S> for Parameter
|
//! impl<S> FromRequestParts<S> for Parameter
|
||||||
//! where
|
//! where
|
||||||
//! S: Send + Sync,
|
//! S: Send + Sync,
|
||||||
@@ -242,7 +241,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[axum::async_trait]
|
//!
|
||||||
//! impl<S> FromRequestParts<S> for Parameter
|
//! impl<S> FromRequestParts<S> for Parameter
|
||||||
//! where
|
//! where
|
||||||
//! S: Send + Sync,
|
//! S: Send + Sync,
|
||||||
@@ -332,7 +331,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[axum::async_trait]
|
//!
|
||||||
//! impl<S> FromRequestParts<S> for Parameter
|
//! impl<S> FromRequestParts<S> for Parameter
|
||||||
//! where
|
//! where
|
||||||
//! S: Send + Sync,
|
//! S: Send + Sync,
|
||||||
@@ -407,7 +406,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[axum::async_trait]
|
//!
|
||||||
//! impl<S> FromRequestParts<S> for Parameter
|
//! impl<S> FromRequestParts<S> for Parameter
|
||||||
//! where
|
//! where
|
||||||
//! S: Send + Sync,
|
//! S: Send + Sync,
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ mod tests {
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
impl<T: ValidTestParameter + Serialize> ValidTest for Form<T> {
|
impl<T: ValidTestParameter + Serialize> ValidTest for Form<T> {
|
||||||
const ERROR_STATUS_CODE: StatusCode = StatusCode::BAD_REQUEST;
|
const ERROR_STATUS_CODE: StatusCode = StatusCode::UNPROCESSABLE_ENTITY;
|
||||||
|
|
||||||
fn set_valid_request(builder: RequestBuilder) -> RequestBuilder {
|
fn set_valid_request(builder: RequestBuilder) -> RequestBuilder {
|
||||||
builder.form(T::valid())
|
builder.form(T::valid())
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[derive(TypedPath, Deserialize, Validate)]
|
//! #[derive(TypedPath, Deserialize, Validate)]
|
||||||
//! #[typed_path("/extra_typed_path/:v0/:v1")]
|
//! #[typed_path("/extra_typed_path/{v0}/{v1}")]
|
||||||
//! struct Parameter {
|
//! struct Parameter {
|
||||||
//! #[validate(range(min = 5, max = 10))]
|
//! #[validate(range(min = 5, max = 10))]
|
||||||
//! v0: i32,
|
//! v0: i32,
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! #[derive(TypedPath, Deserialize, Validate)]
|
//! #[derive(TypedPath, Deserialize, Validate)]
|
||||||
//! #[typed_path("/extra_typed_path/:v0/:v1")]
|
//! #[typed_path("/extra_typed_path/{v0}/{v1}")]
|
||||||
//! struct Parameter {
|
//! struct Parameter {
|
||||||
//! #[garde(range(min = 5, max = 10))]
|
//! #[garde(range(min = 5, max = 10))]
|
||||||
//! v0: i32,
|
//! v0: i32,
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
use crate::{HasValidate, ValidationRejection};
|
use crate::{HasValidate, ValidationRejection};
|
||||||
use axum::async_trait;
|
|
||||||
use axum::extract::{FromRef, FromRequest, FromRequestParts, Request};
|
use axum::extract::{FromRef, FromRequest, FromRequestParts, Request};
|
||||||
use axum::http::request::Parts;
|
use axum::http::request::Parts;
|
||||||
use garde::{Report, Validate};
|
use garde::{Report, Validate};
|
||||||
@@ -62,7 +61,10 @@ impl<T> aide::OperationInput for Garde<T>
|
|||||||
where
|
where
|
||||||
T: aide::OperationInput,
|
T: aide::OperationInput,
|
||||||
{
|
{
|
||||||
fn operation_input(ctx: &mut aide::gen::GenContext, operation: &mut aide::openapi::Operation) {
|
fn operation_input(
|
||||||
|
ctx: &mut aide::generate::GenContext,
|
||||||
|
operation: &mut aide::openapi::Operation,
|
||||||
|
) {
|
||||||
T::operation_input(ctx, operation);
|
T::operation_input(ctx, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,6 @@ impl<E> From<Report> for GardeRejection<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor, Context> FromRequest<State> for Garde<Extractor>
|
impl<State, Extractor, Context> FromRequest<State> for Garde<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -98,7 +99,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor, Context> FromRequestParts<State> for Garde<Extractor>
|
impl<State, Extractor, Context> FromRequestParts<State> for Garde<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
//! # Test for garde
|
||||||
|
//!
|
||||||
|
|
||||||
#![cfg(feature = "garde")]
|
#![cfg(feature = "garde")]
|
||||||
|
|
||||||
use crate::tests::{ValidTest, ValidTestParameter};
|
use crate::tests::{ValidTest, ValidTestParameter};
|
||||||
@@ -15,6 +18,8 @@ use std::net::SocketAddr;
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
|
||||||
|
/// ParametersGarde
|
||||||
|
///
|
||||||
#[derive(Clone, Deserialize, Serialize, Validate, Eq, PartialEq)]
|
#[derive(Clone, Deserialize, Serialize, Validate, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "extra_protobuf", derive(prost::Message))]
|
#[cfg_attr(feature = "extra_protobuf", derive(prost::Message))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
@@ -434,6 +439,8 @@ async fn test_main() -> anyhow::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test Executor
|
||||||
|
///
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TestExecutor {
|
pub struct TestExecutor {
|
||||||
client: reqwest::Client,
|
client: reqwest::Client,
|
||||||
@@ -496,6 +503,7 @@ impl TestExecutor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get reqwest client reference
|
||||||
pub fn client(&self) -> &reqwest::Client {
|
pub fn client(&self) -> &reqwest::Client {
|
||||||
&self.client
|
&self.client
|
||||||
}
|
}
|
||||||
@@ -514,7 +522,7 @@ pub async fn check_json(type_name: &'static str, response: reqwest::Response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod route {
|
mod route {
|
||||||
pub const PATH: &str = "/path/:v0/:v1";
|
pub const PATH: &str = "/path/{v0}/{v1}";
|
||||||
pub const QUERY: &str = "/query";
|
pub const QUERY: &str = "/query";
|
||||||
pub const FORM: &str = "/form";
|
pub const FORM: &str = "/form";
|
||||||
pub const JSON: &str = "/json";
|
pub const JSON: &str = "/json";
|
||||||
@@ -692,7 +700,7 @@ mod extra {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
|
// 1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
|
||||||
#[axum::async_trait]
|
|
||||||
impl<S> FromRequestParts<S> for ParametersGarde
|
impl<S> FromRequestParts<S> for ParametersGarde
|
||||||
where
|
where
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
@@ -812,11 +820,11 @@ mod extra_typed_path {
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
pub mod route {
|
pub mod route {
|
||||||
pub const EXTRA_TYPED_PATH: &str = "/extra_typed_path/:v0/:v1";
|
pub const EXTRA_TYPED_PATH: &str = "/extra_typed_path/{v0}/{v1}";
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Validate, TypedPath, Deserialize)]
|
#[derive(Validate, TypedPath, Deserialize)]
|
||||||
#[typed_path("/extra_typed_path/:v0/:v1")]
|
#[typed_path("/extra_typed_path/{v0}/{v1}")]
|
||||||
pub struct TypedPathParam {
|
pub struct TypedPathParam {
|
||||||
#[garde(range(min = 5, max = 10))]
|
#[garde(range(min = 5, max = 10))]
|
||||||
v0: i32,
|
v0: i32,
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
use crate::{HasValidate, ValidationRejection};
|
use crate::{HasValidate, ValidationRejection};
|
||||||
use axum::async_trait;
|
|
||||||
use axum::extract::{FromRef, FromRequest, FromRequestParts, Request};
|
use axum::extract::{FromRef, FromRequest, FromRequestParts, Request};
|
||||||
use axum::http::request::Parts;
|
use axum::http::request::Parts;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
@@ -62,7 +61,10 @@ impl<T> aide::OperationInput for Valid<T>
|
|||||||
where
|
where
|
||||||
T: aide::OperationInput,
|
T: aide::OperationInput,
|
||||||
{
|
{
|
||||||
fn operation_input(ctx: &mut aide::gen::GenContext, operation: &mut aide::openapi::Operation) {
|
fn operation_input(
|
||||||
|
ctx: &mut aide::generate::GenContext,
|
||||||
|
operation: &mut aide::openapi::Operation,
|
||||||
|
) {
|
||||||
T::operation_input(ctx, operation);
|
T::operation_input(ctx, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +120,10 @@ impl<T> aide::OperationInput for ValidEx<T>
|
|||||||
where
|
where
|
||||||
T: aide::OperationInput,
|
T: aide::OperationInput,
|
||||||
{
|
{
|
||||||
fn operation_input(ctx: &mut aide::gen::GenContext, operation: &mut aide::openapi::Operation) {
|
fn operation_input(
|
||||||
|
ctx: &mut aide::generate::GenContext,
|
||||||
|
operation: &mut aide::openapi::Operation,
|
||||||
|
) {
|
||||||
T::operation_input(ctx, operation);
|
T::operation_input(ctx, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +149,6 @@ pub trait HasValidateArgs<'v> {
|
|||||||
fn get_validate_args(&self) -> &Self::ValidateArgs;
|
fn get_validate_args(&self) -> &Self::ValidateArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequest<State> for Valid<Extractor>
|
impl<State, Extractor> FromRequest<State> for Valid<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -162,7 +166,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequestParts<State> for Valid<Extractor>
|
impl<State, Extractor> FromRequestParts<State> for Valid<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -180,7 +183,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor, Args> FromRequest<State> for ValidEx<Extractor>
|
impl<State, Extractor, Args> FromRequest<State> for ValidEx<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -201,7 +203,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor, Args> FromRequestParts<State> for ValidEx<Extractor>
|
impl<State, Extractor, Args> FromRequestParts<State> for ValidEx<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -221,6 +222,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// basic tests for validator
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
//! # Test for validator
|
||||||
|
//!
|
||||||
|
|
||||||
#![cfg(feature = "validator")]
|
#![cfg(feature = "validator")]
|
||||||
|
|
||||||
use crate::tests::{ValidTest, ValidTestParameter};
|
use crate::tests::{ValidTest, ValidTestParameter};
|
||||||
@@ -16,6 +19,8 @@ use std::sync::Arc;
|
|||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use validator::{Validate, ValidateArgs, ValidationError};
|
use validator::{Validate, ValidateArgs, ValidationError};
|
||||||
|
|
||||||
|
/// Parameters
|
||||||
|
///
|
||||||
#[derive(Clone, Deserialize, Serialize, Validate, Eq, PartialEq)]
|
#[derive(Clone, Deserialize, Serialize, Validate, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "extra_protobuf", derive(prost::Message))]
|
#[cfg_attr(feature = "extra_protobuf", derive(prost::Message))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
@@ -31,6 +36,8 @@ pub struct Parameters {
|
|||||||
v1: String,
|
v1: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ParametersEx
|
||||||
|
///
|
||||||
#[derive(Clone, Deserialize, Serialize, Validate, Eq, PartialEq)]
|
#[derive(Clone, Deserialize, Serialize, Validate, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "extra_protobuf", derive(prost::Message))]
|
#[cfg_attr(feature = "extra_protobuf", derive(prost::Message))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
@@ -69,6 +76,8 @@ struct ParametersExValidationArgumentsInner {
|
|||||||
v1_length_range: RangeInclusive<usize>,
|
v1_length_range: RangeInclusive<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ParametersExValidationArguments
|
||||||
|
///
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct ParametersExValidationArguments {
|
pub struct ParametersExValidationArguments {
|
||||||
inner: Arc<ParametersExValidationArgumentsInner>,
|
inner: Arc<ParametersExValidationArgumentsInner>,
|
||||||
@@ -115,7 +124,7 @@ impl HasValidate for Parameters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'v> HasValidateArgs<'v> for ParametersEx {
|
impl HasValidateArgs<'_> for ParametersEx {
|
||||||
type ValidateArgs = ParametersEx;
|
type ValidateArgs = ParametersEx;
|
||||||
|
|
||||||
fn get_validate_args(&self) -> &Self::ValidateArgs {
|
fn get_validate_args(&self) -> &Self::ValidateArgs {
|
||||||
@@ -663,6 +672,7 @@ async fn test_main() -> anyhow::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test Executor
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TestExecutor {
|
pub struct TestExecutor {
|
||||||
client: reqwest::Client,
|
client: reqwest::Client,
|
||||||
@@ -725,6 +735,7 @@ impl TestExecutor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get reqwest client reference
|
||||||
pub fn client(&self) -> &reqwest::Client {
|
pub fn client(&self) -> &reqwest::Client {
|
||||||
&self.client
|
&self.client
|
||||||
}
|
}
|
||||||
@@ -743,8 +754,8 @@ pub async fn check_json(type_name: &'static str, response: reqwest::Response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod route {
|
mod route {
|
||||||
pub const PATH: &str = "/path/:v0/:v1";
|
pub const PATH: &str = "/path/{v0}/{v1}";
|
||||||
pub const PATH_EX: &str = "/path_ex/:v0/:v1";
|
pub const PATH_EX: &str = "/path_ex/{v0}/{v1}";
|
||||||
pub const QUERY: &str = "/query";
|
pub const QUERY: &str = "/query";
|
||||||
pub const QUERY_EX: &str = "/query_ex";
|
pub const QUERY_EX: &str = "/query_ex";
|
||||||
pub const FORM: &str = "/form";
|
pub const FORM: &str = "/form";
|
||||||
@@ -1036,7 +1047,7 @@ mod extra {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
|
// 1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
|
||||||
#[axum::async_trait]
|
|
||||||
impl<S> FromRequestParts<S> for Parameters
|
impl<S> FromRequestParts<S> for Parameters
|
||||||
where
|
where
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
@@ -1052,7 +1063,6 @@ mod extra {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[axum::async_trait]
|
|
||||||
impl<S> FromRequestParts<S> for ParametersEx
|
impl<S> FromRequestParts<S> for ParametersEx
|
||||||
where
|
where
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
@@ -1198,12 +1208,12 @@ mod extra_typed_path {
|
|||||||
use validator::{Validate, ValidationError};
|
use validator::{Validate, ValidationError};
|
||||||
|
|
||||||
pub mod route {
|
pub mod route {
|
||||||
pub const EXTRA_TYPED_PATH: &str = "/extra_typed_path/:v0/:v1";
|
pub const EXTRA_TYPED_PATH: &str = "/extra_typed_path/{v0}/{v1}";
|
||||||
pub const EXTRA_TYPED_PATH_EX: &str = "/extra_typed_path_ex/:v0/:v1";
|
pub const EXTRA_TYPED_PATH_EX: &str = "/extra_typed_path_ex/{v0}/{v1}";
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Validate, TypedPath, Deserialize)]
|
#[derive(Validate, TypedPath, Deserialize)]
|
||||||
#[typed_path("/extra_typed_path/:v0/:v1")]
|
#[typed_path("/extra_typed_path/{v0}/{v1}")]
|
||||||
pub struct TypedPathParam {
|
pub struct TypedPathParam {
|
||||||
#[validate(range(min = 5, max = 10))]
|
#[validate(range(min = 5, max = 10))]
|
||||||
v0: i32,
|
v0: i32,
|
||||||
@@ -1244,7 +1254,7 @@ mod extra_typed_path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Validate, TypedPath, Deserialize)]
|
#[derive(Validate, TypedPath, Deserialize)]
|
||||||
#[typed_path("/extra_typed_path_ex/:v0/:v1")]
|
#[typed_path("/extra_typed_path_ex/{v0}/{v1}")]
|
||||||
#[validate(context = TypedPathParamExValidationArguments)]
|
#[validate(context = TypedPathParamExValidationArguments)]
|
||||||
pub struct TypedPathParamEx {
|
pub struct TypedPathParamEx {
|
||||||
#[validate(custom(function = "validate_v0", use_context))]
|
#[validate(custom(function = "validate_v0", use_context))]
|
||||||
@@ -1253,7 +1263,7 @@ mod extra_typed_path {
|
|||||||
v1: String,
|
v1: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'v> HasValidateArgs<'v> for TypedPathParamEx {
|
impl HasValidateArgs<'_> for TypedPathParamEx {
|
||||||
type ValidateArgs = Self;
|
type ValidateArgs = Self;
|
||||||
|
|
||||||
fn get_validate_args(&self) -> &Self::ValidateArgs {
|
fn get_validate_args(&self) -> &Self::ValidateArgs {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
use crate::{HasValidate, ValidationRejection};
|
use crate::{HasValidate, ValidationRejection};
|
||||||
use axum::async_trait;
|
|
||||||
use axum::extract::{FromRequest, FromRequestParts, Request};
|
use axum::extract::{FromRequest, FromRequestParts, Request};
|
||||||
use axum::http::request::Parts;
|
use axum::http::request::Parts;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
@@ -61,7 +60,10 @@ impl<T> aide::OperationInput for Validated<T>
|
|||||||
where
|
where
|
||||||
T: aide::OperationInput,
|
T: aide::OperationInput,
|
||||||
{
|
{
|
||||||
fn operation_input(ctx: &mut aide::gen::GenContext, operation: &mut aide::openapi::Operation) {
|
fn operation_input(
|
||||||
|
ctx: &mut aide::generate::GenContext,
|
||||||
|
operation: &mut aide::openapi::Operation,
|
||||||
|
) {
|
||||||
T::operation_input(ctx, operation);
|
T::operation_input(ctx, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,7 +129,10 @@ impl<T> aide::OperationInput for Modified<T>
|
|||||||
where
|
where
|
||||||
T: aide::OperationInput,
|
T: aide::OperationInput,
|
||||||
{
|
{
|
||||||
fn operation_input(ctx: &mut aide::gen::GenContext, operation: &mut aide::openapi::Operation) {
|
fn operation_input(
|
||||||
|
ctx: &mut aide::generate::GenContext,
|
||||||
|
operation: &mut aide::openapi::Operation,
|
||||||
|
) {
|
||||||
T::operation_input(ctx, operation);
|
T::operation_input(ctx, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,14 +145,14 @@ where
|
|||||||
type Inner = T::Inner;
|
type Inner = T::Inner;
|
||||||
|
|
||||||
fn operation_response(
|
fn operation_response(
|
||||||
ctx: &mut aide::gen::GenContext,
|
ctx: &mut aide::generate::GenContext,
|
||||||
operation: &mut aide::openapi::Operation,
|
operation: &mut aide::openapi::Operation,
|
||||||
) -> Option<aide::openapi::Response> {
|
) -> Option<aide::openapi::Response> {
|
||||||
T::operation_response(ctx, operation)
|
T::operation_response(ctx, operation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inferred_responses(
|
fn inferred_responses(
|
||||||
ctx: &mut aide::gen::GenContext,
|
ctx: &mut aide::generate::GenContext,
|
||||||
operation: &mut aide::openapi::Operation,
|
operation: &mut aide::openapi::Operation,
|
||||||
) -> Vec<(Option<u16>, aide::openapi::Response)> {
|
) -> Vec<(Option<u16>, aide::openapi::Response)> {
|
||||||
T::inferred_responses(ctx, operation)
|
T::inferred_responses(ctx, operation)
|
||||||
@@ -200,7 +205,10 @@ impl<T> aide::OperationInput for Validified<T>
|
|||||||
where
|
where
|
||||||
T: aide::OperationInput,
|
T: aide::OperationInput,
|
||||||
{
|
{
|
||||||
fn operation_input(ctx: &mut aide::gen::GenContext, operation: &mut aide::openapi::Operation) {
|
fn operation_input(
|
||||||
|
ctx: &mut aide::generate::GenContext,
|
||||||
|
operation: &mut aide::openapi::Operation,
|
||||||
|
) {
|
||||||
T::operation_input(ctx, operation);
|
T::operation_input(ctx, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,7 +257,10 @@ impl<T> aide::OperationInput for ValidifiedByRef<T>
|
|||||||
where
|
where
|
||||||
T: aide::OperationInput,
|
T: aide::OperationInput,
|
||||||
{
|
{
|
||||||
fn operation_input(ctx: &mut aide::gen::GenContext, operation: &mut aide::openapi::Operation) {
|
fn operation_input(
|
||||||
|
ctx: &mut aide::generate::GenContext,
|
||||||
|
operation: &mut aide::openapi::Operation,
|
||||||
|
) {
|
||||||
T::operation_input(ctx, operation);
|
T::operation_input(ctx, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,7 +312,6 @@ pub trait HasValidify: Sized {
|
|||||||
fn from_validify(v: Self::Validify) -> Self;
|
fn from_validify(v: Self::Validify) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequest<State> for Validated<Extractor>
|
impl<State, Extractor> FromRequest<State> for Validated<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -319,7 +329,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequestParts<State> for Validated<Extractor>
|
impl<State, Extractor> FromRequestParts<State> for Validated<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -337,7 +346,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequest<State> for Modified<Extractor>
|
impl<State, Extractor> FromRequest<State> for Modified<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -352,7 +360,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequestParts<State> for Modified<Extractor>
|
impl<State, Extractor> FromRequestParts<State> for Modified<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -367,7 +374,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequest<State> for Validified<Extractor>
|
impl<State, Extractor> FromRequest<State> for Validified<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -387,7 +393,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequestParts<State> for Validified<Extractor>
|
impl<State, Extractor> FromRequestParts<State> for Validified<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -407,7 +412,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequest<State> for ValidifiedByRef<Extractor>
|
impl<State, Extractor> FromRequest<State> for ValidifiedByRef<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
@@ -426,7 +430,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<State, Extractor> FromRequestParts<State> for ValidifiedByRef<Extractor>
|
impl<State, Extractor> FromRequestParts<State> for ValidifiedByRef<Extractor>
|
||||||
where
|
where
|
||||||
State: Send + Sync,
|
State: Send + Sync,
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
|
//! # Test for validify
|
||||||
|
//!
|
||||||
|
|
||||||
#![cfg(feature = "validify")]
|
#![cfg(feature = "validify")]
|
||||||
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
use crate::tests::{ValidTest, ValidTestParameter};
|
use crate::tests::{ValidTest, ValidTestParameter};
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -19,6 +23,8 @@ use std::ops::Deref;
|
|||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use validify::{Modify, Payload, Validate, Validify};
|
use validify::{Modify, Payload, Validate, Validify};
|
||||||
|
|
||||||
|
/// ParametersValidify
|
||||||
|
///
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, Validify, Payload, Eq, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, Validify, Payload, Eq, PartialEq)]
|
||||||
pub struct ParametersValidify {
|
pub struct ParametersValidify {
|
||||||
#[validate(range(min = 5.0, max = 10.0))]
|
#[validate(range(min = 5.0, max = 10.0))]
|
||||||
@@ -28,6 +34,8 @@ pub struct ParametersValidify {
|
|||||||
v1: String,
|
v1: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ParametersValidifyWithoutPayload
|
||||||
|
///
|
||||||
#[derive(Clone, Validify, Eq, PartialEq)]
|
#[derive(Clone, Validify, Eq, PartialEq)]
|
||||||
#[cfg_attr(feature = "extra_protobuf", derive(Message))]
|
#[cfg_attr(feature = "extra_protobuf", derive(Message))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
@@ -82,7 +90,7 @@ impl ValidTestParameter for ParametersValidify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn error() -> &'static [(&'static str, &'static str)] {
|
fn error() -> &'static [(&'static str, &'static str)] {
|
||||||
&[("not_v0_or_v1", "value")]
|
&[("v0", "not_a_number"), ("v1", "string")]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invalid() -> &'static Self {
|
fn invalid() -> &'static Self {
|
||||||
@@ -1110,6 +1118,8 @@ async fn test_main() -> anyhow::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test Executor
|
||||||
|
///
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TestExecutor {
|
pub struct TestExecutor {
|
||||||
client: reqwest::Client,
|
client: reqwest::Client,
|
||||||
@@ -1156,7 +1166,7 @@ impl TestExecutor {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute all tests for `Modified` without validation
|
/// Execute all tests for `Validified` without validation
|
||||||
pub async fn execute_validified<T: ValidTest>(
|
pub async fn execute_validified<T: ValidTest>(
|
||||||
&self,
|
&self,
|
||||||
method: Method,
|
method: Method,
|
||||||
@@ -1166,7 +1176,7 @@ impl TestExecutor {
|
|||||||
method,
|
method,
|
||||||
route,
|
route,
|
||||||
StatusCode::OK,
|
StatusCode::OK,
|
||||||
T::INVALID_STATUS_CODE,
|
T::ERROR_STATUS_CODE,
|
||||||
T::INVALID_STATUS_CODE,
|
T::INVALID_STATUS_CODE,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
@@ -1230,6 +1240,7 @@ impl TestExecutor {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get reqwest client reference
|
||||||
pub fn client(&self) -> &reqwest::Client {
|
pub fn client(&self) -> &reqwest::Client {
|
||||||
&self.client
|
&self.client
|
||||||
}
|
}
|
||||||
@@ -1248,23 +1259,23 @@ pub async fn check_json(type_name: &'static str, response: reqwest::Response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod route {
|
mod route {
|
||||||
pub const PATH: &str = "/path/:v0/:v1";
|
pub const PATH: &str = "/path/{v0}/{v1}";
|
||||||
pub const PATH_MODIFIED: &str = "/path_modified/:v0/:v1";
|
pub const PATH_MODIFIED: &str = "/path_modified/{v0}/{v1}";
|
||||||
pub const PATH_VALIDIFIED: &str = "/path_validified/:v0/:v1";
|
pub const PATH_VALIDIFIED: &str = "/path_validified/{v0}/{v1}";
|
||||||
pub const PATH_VALIDIFIED_BY_REF: &str = "/path_validified_by_ref/:v0/:v1";
|
pub const PATH_VALIDIFIED_BY_REF: &str = "/path_validified_by_ref/{v0}/{v1}";
|
||||||
pub const QUERY: &str = "/query";
|
pub const QUERY: &str = "/query";
|
||||||
pub const QUERY_MODIFIED: &str = "/query_modified/:v0/:v1";
|
pub const QUERY_MODIFIED: &str = "/query_modified/{v0}/{v1}";
|
||||||
|
|
||||||
pub const QUERY_VALIDIFIED: &str = "/query_validified/:v0/:v1";
|
pub const QUERY_VALIDIFIED: &str = "/query_validified/{v0}/{v1}";
|
||||||
pub const QUERY_VALIDIFIED_BY_REF: &str = "/query_validified_by_ref/:v0/:v1";
|
pub const QUERY_VALIDIFIED_BY_REF: &str = "/query_validified_by_ref/{v0}/{v1}";
|
||||||
pub const FORM: &str = "/form";
|
pub const FORM: &str = "/form";
|
||||||
pub const FORM_MODIFIED: &str = "/form_modified/:v0/:v1";
|
pub const FORM_MODIFIED: &str = "/form_modified/{v0}/{v1}";
|
||||||
pub const FORM_VALIDIFIED: &str = "/form_validified/:v0/:v1";
|
pub const FORM_VALIDIFIED: &str = "/form_validified/{v0}/{v1}";
|
||||||
pub const FORM_VALIDIFIED_BY_REF: &str = "/form_validified_by_ref/:v0/:v1";
|
pub const FORM_VALIDIFIED_BY_REF: &str = "/form_validified_by_ref/{v0}/{v1}";
|
||||||
pub const JSON: &str = "/json";
|
pub const JSON: &str = "/json";
|
||||||
pub const JSON_MODIFIED: &str = "/json_modified/:v0/:v1";
|
pub const JSON_MODIFIED: &str = "/json_modified/{v0}/{v1}";
|
||||||
pub const JSON_VALIDIFIED: &str = "/json_validified/:v0/:v1";
|
pub const JSON_VALIDIFIED: &str = "/json_validified/{v0}/{v1}";
|
||||||
pub const JSON_VALIDIFIED_BY_REF: &str = "/json_validified_by_ref/:v0/:v1";
|
pub const JSON_VALIDIFIED_BY_REF: &str = "/json_validified_by_ref/{v0}/{v1}";
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn extract_path(
|
async fn extract_path(
|
||||||
@@ -1602,7 +1613,7 @@ mod extra {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
|
// 1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
|
||||||
#[axum::async_trait]
|
|
||||||
impl<S> FromRequestParts<S> for ParametersValidify
|
impl<S> FromRequestParts<S> for ParametersValidify
|
||||||
where
|
where
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
@@ -1776,14 +1787,14 @@ mod extra_typed_path {
|
|||||||
use validify::{Validate, Validify};
|
use validify::{Validate, Validify};
|
||||||
|
|
||||||
pub mod route {
|
pub mod route {
|
||||||
pub const EXTRA_TYPED_PATH: &str = "/extra_typed_path/:v0/:v1";
|
pub const EXTRA_TYPED_PATH: &str = "/extra_typed_path/{v0}/{v1}";
|
||||||
pub const EXTRA_TYPED_PATH_MODIFIED: &str = "/extra_typed_path_modified/:v0/:v1";
|
pub const EXTRA_TYPED_PATH_MODIFIED: &str = "/extra_typed_path_modified/{v0}/{v1}";
|
||||||
pub const EXTRA_TYPED_PATH_VALIDIFIED_BY_REF: &str =
|
pub const EXTRA_TYPED_PATH_VALIDIFIED_BY_REF: &str =
|
||||||
"/extra_typed_path_validified_by_ref/:v0/:v1";
|
"/extra_typed_path_validified_by_ref/{v0}/{v1}";
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Validate, TypedPath, Deserialize)]
|
#[derive(Validate, TypedPath, Deserialize)]
|
||||||
#[typed_path("/extra_typed_path/:v0/:v1")]
|
#[typed_path("/extra_typed_path/{v0}/{v1}")]
|
||||||
pub struct TypedPathParam {
|
pub struct TypedPathParam {
|
||||||
#[validate(range(min = 5.0, max = 10.0))]
|
#[validate(range(min = 5.0, max = 10.0))]
|
||||||
v0: i32,
|
v0: i32,
|
||||||
@@ -1800,7 +1811,7 @@ mod extra_typed_path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Validify, TypedPath, Deserialize, Clone, PartialEq, Eq)]
|
#[derive(Validify, TypedPath, Deserialize, Clone, PartialEq, Eq)]
|
||||||
#[typed_path("/extra_typed_path_validified_by_ref/:v0/:v1")]
|
#[typed_path("/extra_typed_path_validified_by_ref/{v0}/{v1}")]
|
||||||
pub struct TypedPathParamValidifiedByRef {
|
pub struct TypedPathParamValidifiedByRef {
|
||||||
#[validate(range(min = 5.0, max = 10.0))]
|
#[validate(range(min = 5.0, max = 10.0))]
|
||||||
v0: i32,
|
v0: i32,
|
||||||
@@ -1826,7 +1837,7 @@ mod extra_typed_path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Validify, TypedPath, Deserialize, Clone, PartialEq, Eq)]
|
#[derive(Validify, TypedPath, Deserialize, Clone, PartialEq, Eq)]
|
||||||
#[typed_path("/extra_typed_path_modified/:v0/:v1")]
|
#[typed_path("/extra_typed_path_modified/{v0}/{v1}")]
|
||||||
pub struct TypedPathParamModified {
|
pub struct TypedPathParamModified {
|
||||||
#[validate(range(min = 5.0, max = 10.0))]
|
#[validate(range(min = 5.0, max = 10.0))]
|
||||||
v0: i32,
|
v0: i32,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ impl IntoResponse for MyDataRejection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
|
// 1.3. Implement your extractor (`FromRequestParts` or `FromRequest`)
|
||||||
#[axum::async_trait]
|
|
||||||
impl<S> FromRequestParts<S> for MyData
|
impl<S> FromRequestParts<S> for MyData
|
||||||
where
|
where
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
|
|||||||
Reference in New Issue
Block a user