1#[macro_use]
16extern crate lazy_static;
17
18pub mod email;
19pub mod error;
20pub mod ip;
21pub mod length;
22pub mod r#match;
23pub mod url;
24
25use std::{borrow::Cow, collections::BTreeMap};
26
27pub trait Prove {
28 fn prove(&self) -> Result<(), error::ValidationError>;
29}
30
31impl<T> Prove for Option<T>
32where
33 T: Prove,
34{
35 fn prove(&self) -> Result<(), error::ValidationError> {
36 match self {
37 Some(v) => v.prove(),
38 None => Ok(()),
39 }
40 }
41}
42
43impl<T> Prove for Vec<T>
44where
45 T: Prove,
46{
47 fn prove(&self) -> Result<(), error::ValidationError> {
48 let mut errors = BTreeMap::new();
49
50 for (index, item) in self.iter().enumerate() {
51 if let Err(error) = item.prove() {
52 errors.insert(index as u64, error);
53 }
54 }
55
56 if errors.is_empty() {
57 Ok(())
58 } else {
59 Err(error::ValidationError::List(errors))
60 }
61 }
62}
63
64macro_rules! tuple_impls {
65 ($(
66 ($(($idx:tt)),+)
67 )+) => {
68 tuple_impls! {
69 $(
70 ($((T, $idx)),+)
71 )+
72 }
73 };
74 ($(
75 ($(($T:ident, $idx:tt)),+)
76 )+) => {
77 $(
78 impl<T> Prove for ($($T),+) where T: Prove {
79 fn prove(&self) -> Result<(), error::ValidationError> {
80 let mut errors = std::collections::BTreeMap::new();
81
82 $(
83 if let Err(error) = self.$idx.prove() {
84 errors.insert($idx, error);
85 }
86 )+
87
88 if errors.is_empty() {
89 Ok(())
90 } else {
91 Err(error::ValidationError::List(errors))
92 }
93 }
94 }
95 )+
96 };
97}
98
99tuple_impls! {
100 ((0), (1))
101 ((0), (1), (2))
102 ((0), (1), (2), (3))
103 ((0), (1), (2), (3), (4))
104 ((0), (1), (2), (3), (4), (5))
105 ((0), (1), (2), (3), (4), (5), (6))
106 ((0), (1), (2), (3), (4), (5), (6), (7))
107 ((0), (1), (2), (3), (4), (5), (6), (7), (8))
108 ((0), (1), (2), (3), (4), (5), (6), (7), (8), (9))
109 ((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10))
110 ((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11))
111 ((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12))
112}
113
114pub trait AsValidateStr<'a> {
115 fn as_validate_str(&'a self) -> Option<Cow<'a, str>>;
116}
117
118impl<'a> AsValidateStr<'a> for String {
119 fn as_validate_str(&'a self) -> Option<Cow<'a, str>> {
120 Some(Cow::Borrowed(self))
121 }
122}
123
124impl<'a> AsValidateStr<'a> for &'a String {
125 fn as_validate_str(&'a self) -> Option<Cow<'a, str>> {
126 Some(Cow::Borrowed(self))
127 }
128}
129
130impl<'a> AsValidateStr<'a> for &'a str {
131 fn as_validate_str(&'a self) -> Option<Cow<'a, str>> {
132 Some(Cow::Borrowed(self))
133 }
134}
135
136impl<'a, T> AsValidateStr<'a> for Option<T>
137where
138 T: AsValidateStr<'a>,
139{
140 fn as_validate_str(&'a self) -> Option<Cow<'a, str>> {
141 match self {
142 None => None,
143 Some(v) => v.as_validate_str(),
144 }
145 }
146}