1pub mod error;
24
25pub mod validators;
27
28pub use error::{Error, Location};
30
31pub use validatron_derive::Validate;
33
34pub type Result<T> = std::result::Result<T, Error>;
36
37pub trait Validate {
42 fn validate(&self) -> Result<()>;
44}
45
46fn validate_seq<'a, I, T: 'a>(sequence: I) -> Result<()>
47where
48 I: IntoIterator<Item = &'a T>,
49 T: Validate,
50{
51 let mut eb = Error::build();
52
53 for (i, x) in sequence.into_iter().enumerate() {
54 eb.try_at_index(i, x.validate());
55 }
56
57 eb.build()
58}
59
60impl<T> Validate for Vec<T>
61where
62 T: Validate,
63{
64 fn validate(&self) -> Result<()> {
65 validate_seq(self)
66 }
67}
68
69impl<T> Validate for std::collections::VecDeque<T>
70where
71 T: Validate,
72{
73 fn validate(&self) -> Result<()> {
74 validate_seq(self)
75 }
76}
77
78impl<T> Validate for std::collections::LinkedList<T>
79where
80 T: Validate,
81{
82 fn validate(&self) -> Result<()> {
83 validate_seq(self)
84 }
85}
86
87impl<K, V, S> Validate for std::collections::HashMap<K, V, S>
88where
89 K: std::fmt::Display,
90 V: Validate,
91{
92 fn validate(&self) -> Result<()> {
93 let mut eb = Error::build();
94
95 for (k, v) in self {
96 eb.try_at_named(k.to_string(), v.validate());
97 }
98
99 eb.build()
100 }
101}
102
103impl<K, V> Validate for std::collections::BTreeMap<K, V>
104where
105 K: std::fmt::Display,
106 V: Validate,
107{
108 fn validate(&self) -> Result<()> {
109 let mut eb = Error::build();
110
111 for (k, v) in self {
112 eb.try_at_named(k.to_string(), v.validate());
113 }
114
115 eb.build()
116 }
117}
118
119impl<T, S> Validate for std::collections::HashSet<T, S>
120where
121 T: Validate,
122{
123 fn validate(&self) -> Result<()> {
124 validate_seq(self)
125 }
126}
127
128impl<T> Validate for std::collections::BTreeSet<T>
129where
130 T: Validate,
131{
132 fn validate(&self) -> Result<()> {
133 validate_seq(self)
134 }
135}
136
137impl<T> Validate for std::collections::BinaryHeap<T>
138where
139 T: Validate,
140{
141 fn validate(&self) -> Result<()> {
142 validate_seq(self)
143 }
144}
145
146#[cfg(feature = "use-indexmap")]
147impl<K, V> Validate for indexmap::IndexMap<K, V>
148where
149 K: std::fmt::Display,
150 V: Validate,
151{
152 fn validate(&self) -> Result<()> {
153 let mut eb = Error::build();
154
155 for (k, v) in self {
156 eb.try_at_named(k.to_string(), v.validate());
157 }
158
159 eb.build()
160 }
161}
162
163#[cfg(feature = "use-indexmap")]
164impl<T, S> Validate for indexmap::IndexSet<T, S>
165where
166 T: Validate,
167{
168 fn validate(&self) -> Result<()> {
169 validate_seq(self)
170 }
171}
172
173impl<T> Validate for Option<T>
174where
175 T: Validate,
176{
177 fn validate(&self) -> Result<()> {
178 validate_seq(self)
179 }
180}
181
182impl<T, E> Validate for std::result::Result<T, E>
183where
184 T: Validate,
185{
186 fn validate(&self) -> Result<()> {
187 if let Ok(value) = self {
188 value.validate()
189 } else {
190 Err(Error::new("value is an Error"))
191 }
192 }
193}