1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Validation for [deser](https://docs.rs/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>`](Check) 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>`](Validated) 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 [`Validation`] reports 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`](std::num::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.
pub use Check;
pub use __private;
pub use ;
pub use ;
pub use Validated;
pub use ;
pub use ;
// the examples of the readme are tested
;