Skip to main content

prove/
lib.rs

1// Copyright 2019 YechaoLi
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#[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}