nekrochan/src/qsform.rs

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))
})
}
}