validr/
lib.rs

1//! Validr will allow you to modify your payload after it has been deserialized and then
2//! will validate it with the rules you give it.
3//!
4//! usage:
5//! ```rust
6//! #[macro_use]
7//! use validr::*;
8//! use serde::Deserialize;
9//! use actix_web::{web, HttpResponse, ResponseError};
10//!
11//!
12//! #[derive(Clone, Deserialize, Debug)]
13//! struct TestObj {
14//!     pub name: Option<String>,
15//!     pub email: Option<String>,
16//!     pub age: Option<u8>
17//! }
18//!
19//! impl Validation for TestObj {
20//!     fn modifiers(&self) -> Vec<Modifier<Self>> {
21//!         vec![
22//!             modifier_trim!(name),
23//!             modifier_capitalize!(name),
24//!             modifier_lowercase!(email),
25//!         ]
26//!     }
27//!
28//!     fn rules(&self) -> Vec<Rule<Self>> {
29//!         vec![
30//!             rule_required!(name),
31//!             rule_required!(email),
32//!             rule_email!(email),
33//!         ]
34//!     }
35//! }
36//!
37//! async fn test_actix_route_handler(test: web::Json<TestObj>) -> HttpResponse {
38//!     match test.into_inner().validate() {
39//!         Ok(item) => {
40//!             println!("This is your data validated and modified: {:?}", item);
41//!             HttpResponse::Ok().body("Validation passed!")
42//!         },
43//!         Err(e) => e.error_response(),
44//!     }
45//! }
46//! ```
47//!
48//! # Validation rules
49//! There are some rules predefined and provided for you in a form of a macro
50//! to simply include in your validation.
51//!
52//! ## Required
53//!
54//! For `Option<T: ToString + Clone>` it will check if the field is present
55//! For `String` it will check if it's not empty.
56//!
57//! ```rust
58//! #[macro_use]
59//! use validr::*;
60//! #[derive(serde::Deserialize, Clone)]
61//! struct Test {
62//!     field_name_on_self: Option<String>,
63//! }
64//!
65//! impl Validation for Test {
66//!     fn rules(&self) -> Vec<Rule<Self>> {
67//!         vec![rule_required!(field_name_on_self)]
68//!     }
69//! }
70//! ```
71//!
72//! ## Accepted
73//!
74//! This rule will work for `Option<bool>` where it checks if the field is present and true,
75//! and it will work for `bool` where it checks that its true.
76//!
77//! ```rust
78//! #[macro_use]
79//! use validr::*;
80//! #[derive(serde::Deserialize, Clone)]
81//! struct Test {
82//!     field_name_on_self: Option<bool>,
83//! }
84//!
85//! impl Validation for Test {
86//!     fn rules(&self) -> Vec<Rule<Self>> {
87//!         vec![rule_accepted!(field_name_on_self)]
88//!     }
89//! }
90//! ```
91//!
92//! ## Email
93//!
94//! For `Option<T: ToString + Clone>` it will check if the field is present and valid email
95//! For `String` it will check if it's valid email.
96//!
97//! ```rust
98//! #[macro_use]
99//! use validr::*;
100//! #[derive(serde::Deserialize, Clone)]
101//! struct Test {
102//!     field_name_on_self: Option<String>,
103//! }
104//!
105//! impl Validation for Test {
106//!     fn rules(&self) -> Vec<Rule<Self>> {
107//!         vec![rule_email!(field_name_on_self)]
108//!     }
109//! }
110//! ```
111//!
112//! ## Url
113//!
114//! For `Option<T: ToString + Clone>` it will check if the field is present and valid url
115//! For `String` it will check if it's valid url.
116//!
117//! ```rust
118//! #[macro_use]
119//! use validr::*;
120//! #[derive(serde::Deserialize, Clone)]
121//! struct Test {
122//!     field_name_on_self: Option<String>,
123//! }
124//!
125//! impl Validation for Test {
126//!     fn rules(&self) -> Vec<Rule<Self>> {
127//!         vec![rule_url!(field_name_on_self)]
128//!     }
129//! }
130//! ```
131//!
132//! ## Phone
133//!
134//! For `Option<T: ToString + Clone>` it will check if the field is present and valid phone number
135//! For `String` it will check if it's valid phone number.
136//!
137//! ```rust
138//! #[macro_use]
139//! use validr::*;
140//! #[derive(serde::Deserialize, Clone)]
141//! struct Test {
142//!     field_name_on_self: Option<String>,
143//! }
144//!
145//! impl Validation for Test {
146//!     fn rules(&self) -> Vec<Rule<Self>> {
147//!         vec![rule_phone!(field_name_on_self)]
148//!     }
149//! }
150//! ```
151//!
152//! ## Non Control Character
153//!
154//! For `Option<T: ToString + Clone>` it will check if the field is present and has no control characters
155//! For `String` it will check if the field has no control characters
156//!
157//! ```rust
158//! #[macro_use]
159//! use validr::*;
160//! #[derive(serde::Deserialize, Clone)]
161//! struct Test {
162//!     field_name_on_self: Option<String>,
163//! }
164//!
165//! impl Validation for Test {
166//!     fn rules(&self) -> Vec<Rule<Self>> {
167//!         vec![rule_non_control_character!(field_name_on_self)]
168//!     }
169//! }
170//! ```
171//!
172//! ## IP
173//!
174//! For `Option<T: ToString + Clone>` it will check if the field is present and valid IP
175//! For `String` it will check if it's valid IP.
176//!
177//! ```rust
178//! #[macro_use]
179//! use validr::*;
180//! #[derive(serde::Deserialize, Clone)]
181//! struct Test {
182//!     field_name_on_self: Option<String>,
183//! }
184//!
185//! impl Validation for Test {
186//!     fn rules(&self) -> Vec<Rule<Self>> {
187//!         vec![rule_ip!(field_name_on_self)]
188//!     }
189//! }
190//! ```
191//!
192//! ## IP V4
193//!
194//! For `Option<T: ToString + Clone>` it will check if the field is present and valid IP V4
195//! For `String` it will check if it's valid IP V4.
196//!
197//! ```rust
198//! #[macro_use]
199//! use validr::*;
200//! #[derive(serde::Deserialize, Clone)]
201//! struct Test {
202//!     field_name_on_self: Option<String>,
203//! }
204//!
205//! impl Validation for Test {
206//!     fn rules(&self) -> Vec<Rule<Self>> {
207//!         vec![rule_ip_v4!(field_name_on_self)]
208//!     }
209//! }
210//! ```
211//!
212//! ## IP V6
213//!
214//! For `Option<T: ToString + Clone>` it will check if the field is present and valid IP V6
215//! For `String` it will check if it's valid IP V6.
216//!
217//! ```rust
218//! #[macro_use]
219//! use validr::*;
220//! #[derive(serde::Deserialize, Clone)]
221//! struct Test {
222//!     field_name_on_self: Option<String>,
223//! }
224//!
225//! impl Validation for Test {
226//!     fn rules(&self) -> Vec<Rule<Self>> {
227//!         vec![rule_ip_v6!(field_name_on_self)]
228//!     }
229//! }
230//! ```
231//!
232//! ## Credit card
233//!
234//! For `Option<T: ToString + Clone>` it will check if the field is present and valid CC number
235//! For `String` it will check if it's valid CC number.
236//!
237//! ```rust
238//! #[macro_use]
239//! use validr::*;
240//! #[derive(serde::Deserialize, Clone)]
241//! struct Test {
242//!     field_name_on_self: Option<String>,
243//! }
244//!
245//! impl Validation for Test {
246//!     fn rules(&self) -> Vec<Rule<Self>> {
247//!         vec![rule_credit_card!(field_name_on_self)]
248//!     }
249//! }
250//! ```
251//!
252//! ## Contains
253//!
254//! For `Option<T: ToString + Clone>` it will check if the field is present and contains given `needle`
255//! For `String` it will check if it contains given `needle`.
256//!
257//! ```rust
258//! #[macro_use]
259//! use validr::*;
260//! #[derive(serde::Deserialize, Clone)]
261//! struct Test {
262//!     field_name_on_self: Option<String>,
263//! }
264//!
265//! impl Validation for Test {
266//!     fn rules(&self) -> Vec<Rule<Self>> {
267//!         vec![rule_contains!(field_name_on_self, "needle".to_string())]
268//!     }
269//! }
270//! ```
271//!
272//! ## Equal to
273//!
274//! It validates if two given field names are equal.
275//!
276//! ```rust
277//! #[macro_use]
278//! use validr::*;
279//! #[derive(serde::Deserialize, Clone)]
280//! struct Test {
281//!     field_name_on_self: Option<String>,
282//!     field_name_to_compare_to_on_self: Option<String>,
283//! }
284//!
285//! impl Validation for Test {
286//!     fn rules(&self) -> Vec<Rule<Self>> {
287//!         vec![rule_equalt_to!(field_name_on_self, field_name_to_compare_to_on_self)]
288//!     }
289//! }
290//! ```
291//!
292//! ## Not equal to
293//!
294//! It validates if two given field names are not equal.
295//!
296//! ```rust
297//! #[macro_use]
298//! use validr::*;
299//! #[derive(serde::Deserialize, Clone)]
300//! struct Test {
301//!     field_name_on_self: Option<String>,
302//!     field_name_to_compare_to_on_self: Option<String>,
303//! }
304//!
305//! impl Validation for Test {
306//!     fn rules(&self) -> Vec<Rule<Self>> {
307//!         vec![rule_not_equalt_to!(field_name_on_self, field_name_to_compare_to_on_self)]
308//!     }
309//! }
310//! ```
311//!
312//! ## In
313//!
314//! For `Option<T: ToString + Clone>` it will check if the field is present and will match its value to haystack of values
315//! For `String` it will check if its in the haystack value
316//!
317//! ```rust
318//! #[macro_use]
319//! use validr::*;
320//! #[derive(serde::Deserialize, Clone)]
321//! struct Test {
322//!     field_name_on_self: Option<String>,
323//! }
324//!
325//! impl Validation for Test {
326//!     fn rules(&self) -> Vec<Rule<Self>> {
327//!         vec![
328//!             rule_in!(field_name_on_self, vec![
329//!                 "allowed_value".to_string(),
330//!                 "another_allowed_value".to_string()
331//!             ]),
332//!         ]
333//!     }
334//! }
335//! ```
336//!
337//! ## length min
338//!
339//! For `Option<T: ToString + Clone>` it will check if the field is present and has `min` number of chars
340//! For `String` it will check if it has `min` number of chars
341//!
342//! ```rust
343//! #[macro_use]
344//! use validr::*;
345//! #[derive(serde::Deserialize, Clone)]
346//! struct Test {
347//!     field_name_on_self: Option<String>,
348//! }
349//!
350//! impl Validation for Test {
351//!     fn rules(&self) -> Vec<Rule<Self>> {
352//!         vec![rule_length_min!(field_name_on_self, 2)]
353//!     }
354//! }
355//! ```
356//!
357//! ## length max
358//!
359//! For `Option<T: ToString + Clone>` it will check if the field is present and has `max` number of chars
360//! For `String` it will check if it has `max` number of chars
361//!
362//! ```rust
363//! #[macro_use]
364//! use validr::*;
365//! #[derive(serde::Deserialize, Clone)]
366//! struct Test {
367//!     field_name_on_self: Option<String>,
368//! }
369//!
370//! impl Validation for Test {
371//!     fn rules(&self) -> Vec<Rule<Self>> {
372//!         vec![rule_length_max!(field_name_on_self, 15)]
373//!     }
374//! }
375//! ```
376//!
377//! ## length equal
378//!
379//! For `Option<T: ToString + Clone>` it will check if the field is present and has `eq` number of chars
380//! For `String` it will check if it has `eq` number of chars
381//!
382//! ```rust
383//! #[macro_use]
384//! use validr::*;
385//! #[derive(serde::Deserialize, Clone)]
386//! struct Test {
387//!     field_name_on_self: Option<String>,
388//! }
389//!
390//! impl Validation for Test {
391//!     fn rules(&self) -> Vec<Rule<Self>> {
392//!         vec![rule_length_eq!(field_name_on_self, 10)]
393//!     }
394//! }
395//! ```
396//!
397//! ## length not equal
398//!
399//! For `Option<T: ToString + Clone>` it will check if the field is present and has `ne` number of chars
400//! For `String` it will check if it has `ne` number of chars
401//!
402//! ```rust
403//! #[macro_use]
404//! use validr::*;
405//! #[derive(serde::Deserialize, Clone)]
406//! struct Test {
407//!     field_name_on_self: Option<String>,
408//! }
409//!
410//! impl Validation for Test {
411//!     fn rules(&self) -> Vec<Rule<Self>> {
412//!         vec![rule_length_ne!(field_name_on_self, 11)]
413//!     }
414//! }
415//! ```
416//!
417//! ## Range
418//!
419//! For `Option<T: Into<f64> + PartialOrd + Clone>` it will check that the value is present and within given range.
420//! For `T: Into<f64>` it will check if the value is in the given range
421//!
422//! ```rust
423//! #[macro_use]
424//! use validr::*;
425//! #[derive(serde::Deserialize, Clone)]
426//! struct Test {
427//!     field_name_on_self: Option<u8>,
428//! }
429//!
430//! impl Validation for Test {
431//!     fn rules(&self) -> Vec<Rule<Self>> {
432//!         vec![rule_range!(field_name_on_self, Some(10), Some(15))]
433//!     }
434//! }
435//! ```
436//!
437//! ## Custom validation rule
438//!
439//! You can always implement a custom validation rule by instead of using provided
440//! macros generate your own `Rule::new()` definition:
441//!
442//! ```rust
443//! #[macro_use]
444//! use validr::{Validation, error::ValidationError, Rule};
445//! #[derive(serde::Deserialize, Clone)]
446//! struct Test {
447//!     field_name: String,
448//! }
449//!
450//! impl Validation for Test {
451//!     fn rules(&self) -> Vec<Rule<Self>> {
452//!         vec![
453//!             Rule::new("field_name", |obj: &Self, error: &mut ValidationError| {
454//!                 if obj.field_name != "some_validation_rule".to_string() {
455//!                     error.add("my_custom_error_code");
456//!                 }
457//!             }),
458//!         ]
459//!     }
460//! }
461//! ```
462//!
463//! # Field modifiers
464//! Before running validation rules you can modify the input data to format it in whatever way you want.
465//! There are some modifiers included, but you can certainly create a custom one to do whatever you want.
466//!
467//! ## Trim
468//!
469//! For `Option<String>` it will check if there is some value and will run the trim on the value.
470//! For `String` it will simply trim it
471//!
472//! ```rust
473//! #[macro_use]
474//! use validr::*;
475//! #[derive(serde::Deserialize, Clone)]
476//! struct Test {
477//!     field_name_on_self: Option<String>,
478//! }
479//!
480//! impl Validation for Test {
481//!     fn modifiers(&self) -> Vec<Modifier<Self>> {
482//!         vec![modifier_trim!(field_name_on_self)]
483//!     }
484//! }
485//! ```
486//!
487//! ## Lowercase
488//!
489//! For `Option<String>` it will check if there is some value and will run the lowercase on the value.
490//! For `String` it will simply lowercase it
491//!
492//! ```rust
493//! #[macro_use]
494//! use validr::*;
495//! #[derive(serde::Deserialize, Clone)]
496//! struct Test {
497//!     field_name_on_self: Option<String>,
498//! }
499//!
500//! impl Validation for Test {
501//!     fn modifiers(&self) -> Vec<Modifier<Self>> {
502//!         vec![modifier_lowercase!(field_name_on_self)]
503//!     }
504//! }
505//! ```
506//!
507//! ## Uppercase
508//!
509//! For `Option<String>` it will check if there is some value and will run the uppercase on the value.
510//! For `String` it will simply uppercase it
511//!
512//! ```rust
513//! #[macro_use]
514//! use validr::*;
515//! #[derive(serde::Deserialize, Clone)]
516//! struct Test {
517//!     field_name_on_self: Option<String>,
518//! }
519//!
520//! impl Validation for Test {
521//!     fn modifiers(&self) -> Vec<Modifier<Self>> {
522//!         vec![modifier_uppercase!(field_name_on_self)]
523//!     }
524//! }
525//! ```
526//!
527//! ## Capitalize
528//!
529//! For `Option<String>` it will check if there is some value and will run the capitalize on the value.
530//! For `String` it will simply capitalize it
531//!
532//! Capitalize will turn the first char of the string to uppercase, and everything else will be lowercase
533//!
534//! ```rust
535//! #[macro_use]
536//! use validr::*;
537//! #[derive(serde::Deserialize, Clone)]
538//! struct Test {
539//!     field_name_on_self: Option<String>,
540//! }
541//!
542//! impl Validation for Test {
543//!     fn modifiers(&self) -> Vec<Modifier<Self>> {
544//!         vec![modifier_capitalize!(field_name_on_self)]
545//!     }
546//! }
547//! ```
548//!
549//! ## Custom modifier
550//!
551//! Implementing custom modifier is similar to custom validation rule, you will provide a custom
552//! implementation of `Modifier::new()`:
553//!
554//! ```rust
555//! #[macro_use]
556//! use validr::*;
557//! #[derive(serde::Deserialize, Clone)]
558//! struct Test {
559//!     field_name_on_self: Option<String>,
560//! }
561//!
562//! impl Validation for Test {
563//!     fn modifiers(&self) -> Vec<Modifier<Self>> {
564//!         vec![
565//!             Modifier::new("field_name_on_self", |obj: &mut Self| {
566//!                 obj.field_name_on_self = Some("new_value".to_string());
567//!             }),
568//!         ]
569//!     }
570//! }
571//! ```
572//!
573mod modifier;
574mod modifiers;
575mod rule;
576mod rules;
577
578pub mod error;
579pub mod helpers;
580pub mod validator;
581pub mod wrappers;
582
583use serde::Deserialize;
584
585pub use crate::validator::Validator;
586pub use modifier::Modifier;
587pub use modifiers::*;
588pub use rule::Rule;
589pub use rules::*;
590
591pub trait Validation: Clone + for<'de> Deserialize<'de> {
592    /// Method that is intended to return vector of all the validation rules
593    fn rules(&self) -> Vec<Rule<Self>> {
594        vec![]
595    }
596
597    /// Method that is intended to return vector of all the modifications to the object
598    /// before the validation runs
599    fn modifiers(&self) -> Vec<Modifier<Self>> {
600        vec![]
601    }
602
603    /// This will run the validation and return the object if all the validations pass.
604    /// Object will be modified by all the modifiers and ready for using further
605    #[inline]
606    fn validate(self) -> Result<Self, error::ValidationErrors> {
607        let rules = self.rules();
608        let modifiers = self.modifiers();
609
610        let mut validator = Validator::new(self);
611
612        for rule in rules {
613            validator = validator.add_validation(rule);
614        }
615
616        for modifier in modifiers {
617            validator = validator.add_modifier(modifier);
618        }
619
620        validator.run()
621    }
622}
623
624#[cfg(test)]
625mod test;