44 řádky
1.1 KiB
Rust
44 řádky
1.1 KiB
Rust
use actix_web::{dev::Payload, http::StatusCode, FromRequest, HttpRequest, ResponseError};
|
|
use serde::Deserialize;
|
|
use serde_qs::Config;
|
|
use std::{future::Future, pin::Pin};
|
|
use thiserror::Error;
|
|
|
|
pub struct QsForm<T>(pub T)
|
|
where
|
|
T: for<'de> Deserialize<'de>;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum QsFormError {
|
|
#[error("{}", .0)]
|
|
FutureError(#[from] actix_web::Error),
|
|
#[error("{}", .0)]
|
|
ParseError(#[from] serde_qs::Error),
|
|
}
|
|
|
|
impl ResponseError for QsFormError {
|
|
fn status_code(&self) -> StatusCode {
|
|
StatusCode::BAD_REQUEST
|
|
}
|
|
}
|
|
|
|
impl<T> FromRequest for QsForm<T>
|
|
where
|
|
T: for<'de> Deserialize<'de>,
|
|
{
|
|
type Error = QsFormError;
|
|
type Future = Pin<Box<dyn Future<Output = Result<QsForm<T>, Self::Error>>>>;
|
|
|
|
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
|
let data = String::from_request(req, payload);
|
|
|
|
Box::pin(async move {
|
|
let data = data.await?;
|
|
let config = Config::new(10, false);
|
|
let form: T = config.deserialize_str(&data)?;
|
|
|
|
Ok(QsForm(form))
|
|
})
|
|
}
|
|
}
|