garde_actix_web/lib.rs
1//! Actix-web wrapper for [garde](https://github.com/jprochazk/garde), a Rust validation library.
2//!
3//! # Installation
4//!
5//! ```toml
6//! [dependencies]
7//! garde = "0.22"
8//! garde-actix-web = "0.12"
9//! ```
10//!
11//! # Usage example
12//!
13//! Simply use `garde-actix-web` exposed types as a drop in for actix types.
14//!
15//! Your types must implement `Validate` from `garde`. Validation happens during actix's `FromRequest` invocation.
16//!
17//! If the payload is invalid, a 400 error is returned (404 for Path).
18//!
19//! Custom error handling can be implemented with an extractor config (`garde_actix_web::web::QueryConfig` in place of `actix_web::web::QueryConfig` for example).
20//!
21//! ```rust
22//! use actix_web::HttpResponse;
23//! // instead of actix_web::web::Path
24//! use garde_actix_web::web::Path;
25//! use garde::Validate;
26//!
27//! #[derive(Validate)]
28//! struct MyStruct<'a> {
29//! #[garde(ascii, length(min=3, max=25))]
30//! username: &'a str,
31//! }
32//!
33//! fn test(id: Path<MyStruct>) -> HttpResponse {
34//! todo!()
35//! }
36//! ```
37//!
38//! ⚠️ When using `garde` [custom validation](https://github.com/jprochazk/garde#custom-validation), the `Context` type needs to implement `Default` which is not required by `garde`.
39//!
40//! # Feature flags
41//!
42//! | name | description | extra dependencies |
43//! |------------|---------------------------------------------------------------|----------------------------------------------------------------------------------------------|
44//! | `serde_qs` | Enables the usage of `garde` for `serde_qs::actix::QsQuery<T>` | [`serde_qs`](https://crates.io/crates/serde_qs) |
45//!
46//! # Compatibility matrix
47//!
48//! | garde version | serde_qs version | garde-actix-web-version |
49//! |---------------|------------------|-------------------------|
50//! | `0.14` | `0.12` | `0.1.x` |
51//! | `0.15` | `0.12` | `0.2.x` |
52//! | `0.16` | `0.12` | `0.3.x` |
53//! | `0.17` | `0.12` | `0.4.x` |
54//! | `0.18` | `0.12` | `0.5.x`, `0.6.x` |
55//! | `0.18` | `0.13` | `0.7.x` |
56//! | `0.19` | `0.13` | `0.8.x` |
57//! | `0.20` | `0.13` | `0.9.x` |
58//! | `0.20` | `0.13` | `0.10.x` |
59//! | `0.22` | `0.13` | `0.11.x` |
60//! | `0.22` | `0.15` | `0.12.x` |
61
62#![forbid(unsafe_code)]
63
64use actix_web::HttpRequest;
65use actix_web::web::Data;
66use garde::Validate;
67
68pub mod error;
69pub mod web;
70
71fn validate_for_request<T>(data: T, req: &HttpRequest) -> Result<T, error::Error>
72where
73 T: Validate + 'static,
74 T::Context: Default,
75{
76 let context = req
77 .app_data::<T::Context>()
78 .or_else(|| req.app_data::<Data<T::Context>>().map(|d| d.as_ref()));
79
80 match context {
81 None => data.validate().map(|_| data).map_err(Into::into),
82 Some(ctx) => data.validate_with(ctx).map(|_| data).map_err(Into::into),
83 }
84}