actix_quick_extract/
lib.rs

1#![deny(clippy::str_to_string)]
2
3//! # Actix-Quick-Extract
4//!
5//! Extract information from a web request easily.
6use actix_web::{http::header::ToStrError, ResponseError};
7use thiserror::Error;
8
9pub mod headers;
10mod ip_addr;
11#[doc(inline)]
12pub use ip_addr::IpAddr;
13/// Errors that can occur when extracting headers
14///
15/// All Errors return a `400 Bad Request` response
16#[derive(Debug, Error)]
17pub enum ExtractError {
18    #[error("No {0} Header Found")]
19    MissingHeader(&'static str),
20    #[error("Header {0} Header was not valid UTF-8")]
21    ToStrError(&'static str, ToStrError),
22    #[error("Missing {0}")]
23    MissingInfo(&'static str),
24}
25impl ResponseError for ExtractError {
26    fn error_response(&self) -> actix_web::HttpResponse {
27        match self {
28            ExtractError::MissingHeader(header_name) => {
29                actix_web::HttpResponse::BadRequest().body(format!("No {header_name} Header Found"))
30            }
31            ExtractError::ToStrError(header_name, error) => actix_web::HttpResponse::BadRequest()
32                .body(format!("{header_name} Header was not valid UTF-8: {error}")),
33            ExtractError::MissingInfo(name) => {
34                actix_web::HttpResponse::BadRequest().body(format!("Missing {name}"))
35            }
36        }
37    }
38}
39
40macro_rules! ready_impl_from_request {
41    ($f:ty, $fn_name:ident) => {
42        impl FromRequest for $f {
43            type Error = crate::ExtractError;
44            type Future = futures_util::future::Ready<Result<$f, crate::ExtractError>>;
45
46            fn from_request(
47                req: &actix_web::HttpRequest,
48                _: &mut actix_web::dev::Payload,
49            ) -> Self::Future {
50                futures_util::future::ready(<$f>::$fn_name(req))
51            }
52        }
53    };
54    ($f:ty as Header) => {
55        impl FromRequest for $f {
56            type Error = crate::ExtractError;
57            type Future = futures_util::future::Ready<Result<$f, crate::ExtractError>>;
58
59            fn from_request(
60                req: &actix_web::HttpRequest,
61                _: &mut actix_web::dev::Payload,
62            ) -> Self::Future {
63                futures_util::future::ready(<$f as crate::headers::HeaderType>::from_request(req))
64            }
65        }
66    };
67}
68pub(crate) use ready_impl_from_request;