Expand description
Validation library
use garde::{Validate, Valid};
use serde::Deserialize;
#[derive(Deserialize, Validate)]
struct User<'a> {
#[garde(ascii, length(min=3, max=25))]
username: &'a str,
#[garde(length(min=15))]
password: &'a str,
}
let user = serde_json::from_str::<User>(r#"
{
"username": "lolcode",
"password": "hunter2"
}
"#).unwrap();
println!("{}", user.validate(&()).unwrap_err());Garde can also validate enums:
use garde::{Validate, Valid};
use serde::Deserialize;
#[derive(Deserialize, Validate)]
#[serde(rename_all="lowercase")]
enum Data {
Struct {
#[garde(range(min=-10, max=10))]
field: i32,
},
Tuple(
#[garde(rename="important", ascii)]
String
),
}
let data = serde_json::from_str::<Vec<Data>>(r#"
[
{ "struct": { "field": 100 } },
{ "tuple": "test" }
]
"#).unwrap();
for item in &data {
println!("{:?}", item.validate(&()));
}Typestate
This crate supports the typestate pattern via the Unvalidated and Valid types:
use garde::{Valid, Validate, Unvalidated};
#[derive(Debug, Validate)]
struct Test {
#[garde(range(min = 10, max = 100))]
field: u64,
}
let value = Unvalidated::new(Test { field: 20 });
// This is the only method for obtaining a `Valid<T>`
let value: Valid<Test> = value.validate(&()).unwrap();
let value = Unvalidated::new(Test { field: 0 });
println!("{:?}", value.validate(&()));Available validation rules
| name | format | validation | feature flag |
|---|---|---|---|
| ascii | #[garde(ascii)] | only contains ASCII | - |
| alphanumeric | #[garde(alphanumeric)] | only letters and digits | - |
#[garde(email)] | an email according to the HTML5 spec1 | email | |
| url | #[garde(url)] | a URL | url |
| ip | #[garde(ip)] | an IP address (either IPv4 or IPv6) | - |
| ipv4 | #[garde(ipv4)] | an IPv4 address | - |
| ipv6 | #[garde(ipv6)] | an IPv6 address | - |
| credit card | #[garde(credit_card)] | a credit card number | credit-card |
| phone number | #[garde(phone_number)] | a phone number | phone-number |
| length | #[garde(length(min=<usize>, max=<usize>)] | a dynamically-sized value with size in the range min..=max | - |
| range | #[garde(range(min=<expr>, max=<expr>))] | a number in the range min..=max | - |
| contains | #[garde(contains(<string>))] | a string-like value containing a substring | - |
| prefix | #[garde(prefix(<string>))] | a string-like value prefixed by some string | - |
| suffix | #[garde(suffix(<string>))] | a string-like value suffixed by some string | - |
| pattern | #[garde(pattern(<regex>))] | a string-like value matching some regular expression | pattern |
| dive | #[garde(dive)] | nested validation, calls validate on the value | - |
| custom | #[garde(custom(<function or closure>))] | a custom validator | - |
Additional notes:
- For
lengthandrange, eitherminormaxmay be omitted, but not both. lengthandrangeuse an inclusive upper bound (min..=max).lengthuses.chars().count()for UTF-8 strings instead of.len().- For
contains,prefix, andsuffix, the pattern must be a string literal, because thePatternAPI is currently unstable. - Nested validation using
divemay not be combined with any other rule.
Re-exports
pub use error::Error;pub use error::Errors;pub use validate::Unvalidated;pub use validate::Valid;pub use validate::Validate;