Last active: 7 months ago
axum json and form validator
use axum::{
async_trait,
extract::{rejection::FormRejection, FromRequest, Request},
Form, Json,
};
use once_cell::sync::Lazy;
use regex::Regex;
use serde::de::DeserializeOwned;
use validator::Validate;
use crate::error::{AppError, AppResult};
#[derive(Debug, Clone, Copy, Default)]
pub struct ValidatedForm<T>(pub T);
#[async_trait]
impl<T, S> FromRequest<S> for ValidatedForm<T>
where
T: DeserializeOwned + Validate,
S: Send + Sync,
Form<T>: FromRequest<S, Rejection = FormRejection>,
{
type Rejection = AppError;
async fn from_request(req: Request, state: &S) -> AppResult<Self, Self::Rejection> {
let Form(value) = Form::<T>::from_request(req, state).await?;
value.validate()?;
Ok(ValidatedForm(value))
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct ValidatedJson<T>(pub T);
#[async_trait]
impl<T, S> FromRequest<S> for ValidatedJson<T>
where
T: DeserializeOwned + Validate,
S: Send + Sync,
Form<T>: FromRequest<S, Rejection = FormRejection>,
{
type Rejection = AppError;
async fn from_request(req: Request, state: &S) -> AppResult<Self, Self::Rejection> {
let Json(value) = Json::<T>::from_request(req, state).await?;
value.validate()?;
Ok(ValidatedJson(value))
}
}
/// 对用户名的验证
pub static USERNAME_REGEX: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^[(a-zA-Z0-9\u4e00-\u9fa5){1}_#]{1,20}$").unwrap());
/// 对国内手机号对的验证
pub static CN_PHONE_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^(13[0-9]|14[5-9]|15[0-3,5-9]|16[6]|17[0-8]|18[0-9]|19[8,9])\d{8}$").unwrap()
});