Expand description
Validation for deser.
Values are validated while they are deserialized, so errors point at the
value in the input (with its line, column and path) like the errors of
the format. Validators are types (see Validator), so they are
named in adapters and in the types of fields:
- The
Check<V>adapter (#[deser(as = Check<V>)]) fails the deserialization if the value is invalid. The type of the field does not change. On a type (#[deser(deserialize_as = Check<V, _>)]) it checks the whole value, for rules that span fields. Validated<T, V>keeps all errors of the value in it instead of failing, so the value around it can still be deserialized. This also covers errors like a string that is given where a number is expected.- A
Validationreports all problems of an input.
use deser::Deserialize;
use deser_validate::{
Check, Email, MaxLen, NonEmpty, Validated, Validation,
};
#[derive(Deserialize)]
struct Signup {
// must be valid, or the signup is invalid
#[deser(as = Check<(NonEmpty, MaxLen<32>)>)]
name: String,
// kept even if it is invalid
email: Validated<String, Email>,
newsletter: bool,
}
let input = r#"{"name": "", "email": "jane@", "newsletter": "yes"}"#;
let validation = Validation::new();
let rv = deser_json::Deserializer::from_str(input)
.deserialize_with::<Signup, _>(|driver| validation.setup(driver));
let report = validation.finish(rv).into_result().err().unwrap();
let issues: Vec<_> = report
.iter()
.map(|issue| {
format!("{}: {}", issue.path().unwrap(), issue.message())
})
.collect();
assert_eq!(
issues,
[
"name: invalid value: must not be empty",
"email: invalid value: must be an email address",
"newsletter: unexpected string, expected bool",
]
);Types that are always valid are newtypes which check themselves:
use deser::Deserialize;
use deser_validate::Check;
#[derive(Deserialize)]
#[deser(transparent)]
pub struct Email(#[deser(as = Check<deser_validate::Email>)] String);§Validators
The validators of this crate are NonEmpty, Len (and MinLen
and MaxLen), Range (and Min and Max), Email and
Each, which validates the items of collections. Tuples of
validators require all of them. The validator! macro creates
validators from conditions and functions:
use deser::Deserialize;
use deser_validate::{Check, validator};
// a condition and a message
validator!(NonZero(port: &u16) => *port != 0, "must not be zero");
// a function
fn check_host(host: &str) -> Result<(), String> {
match host.contains(' ') {
true => Err(format!("`{}` is not a host name", host)),
false => Ok(()),
}
}
validator!(HostName(host: &str) = check_host);
#[derive(Deserialize)]
struct Server {
#[deser(as = Check<HostName>)]
host: String,
#[deser(as = Check<NonZero>)]
port: u16,
}Validators of types with generics or lifetimes implement Validator
themselves, the macro does not support them.
Validators report a Violation with a code and parameters for
programs and a message for humans. Errors have the violation attached.
§Naming Validators
Validators are named for the property that valid values have, as a
noun or an adjective: Email, Slug, NonEmpty, NonZero,
MaxLen<64>. They read as Check<NonZero> and do not need affixes like
Valid, Is or Rules. Negations start with Non (like
NonZero). Validators of a whole type name the
rule they check (OrderedBounds, not BoundsRules), combinators name
their structure (Each). The code of a violation is the name of the
validator in snake case (max_len, non_zero), for the validators of
this crate and the ones validator! creates.
Macros§
- validator
- Creates a validator type.
Structs§
- Check
- An adapter that validates values with
V. - Each
- Validates every item of a collection with
V. - Requires a string that looks like an email address.
- Issue
- A problem of the input.
- Len
- Requires the length of a string or collection to be in a range.
- NonEmpty
- Requires a string or collection that is not empty.
- Outcome
- The result of a
Validation. - Range
- Requires an integer to be in a range.
- Report
- All problems of an input.
- Validated
- A value that might be invalid, together with its errors.
- Validation
- Finds all problems of an input.
- Violation
- Why a value is invalid.
Enums§
Traits§
- Integer
- Integers (see
Range). - Into
Violation - What the functions of validators fail with.
- Length
- Values that have a length (see
LenandNonEmpty). - Validation
Result - What the functions of validators return.
- Validator
- Validates values of type
T.