#[macro_use]
extern crate lazy_static;
pub mod email;
pub mod error;
pub mod ip;
pub mod length;
pub mod r#match;
pub mod url;
use std::{borrow::Cow, collections::BTreeMap};
pub trait Prove {
fn prove(&self) -> Result<(), error::ValidationError>;
}
impl<T> Prove for Option<T>
where
T: Prove,
{
fn prove(&self) -> Result<(), error::ValidationError> {
match self {
Some(v) => v.prove(),
None => Ok(()),
}
}
}
impl<T> Prove for Vec<T>
where
T: Prove,
{
fn prove(&self) -> Result<(), error::ValidationError> {
let mut errors = BTreeMap::new();
for (index, item) in self.iter().enumerate() {
if let Err(error) = item.prove() {
errors.insert(index as u64, error);
}
}
if errors.is_empty() {
Ok(())
} else {
Err(error::ValidationError::List(errors))
}
}
}
macro_rules! tuple_impls {
($(
($(($idx:tt)),+)
)+) => {
tuple_impls! {
$(
($((T, $idx)),+)
)+
}
};
($(
($(($T:ident, $idx:tt)),+)
)+) => {
$(
impl<T> Prove for ($($T),+) where T: Prove {
fn prove(&self) -> Result<(), error::ValidationError> {
let mut errors = std::collections::BTreeMap::new();
$(
if let Err(error) = self.$idx.prove() {
errors.insert($idx, error);
}
)+
if errors.is_empty() {
Ok(())
} else {
Err(error::ValidationError::List(errors))
}
}
}
)+
};
}
tuple_impls! {
((0), (1))
((0), (1), (2))
((0), (1), (2), (3))
((0), (1), (2), (3), (4))
((0), (1), (2), (3), (4), (5))
((0), (1), (2), (3), (4), (5), (6))
((0), (1), (2), (3), (4), (5), (6), (7))
((0), (1), (2), (3), (4), (5), (6), (7), (8))
((0), (1), (2), (3), (4), (5), (6), (7), (8), (9))
((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10))
((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11))
((0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12))
}
pub trait AsValidateStr<'a> {
fn as_validate_str(&'a self) -> Option<Cow<'a, str>>;
}
impl<'a> AsValidateStr<'a> for String {
fn as_validate_str(&'a self) -> Option<Cow<'a, str>> {
Some(Cow::Borrowed(self))
}
}
impl<'a> AsValidateStr<'a> for &'a String {
fn as_validate_str(&'a self) -> Option<Cow<'a, str>> {
Some(Cow::Borrowed(self))
}
}
impl<'a> AsValidateStr<'a> for &'a str {
fn as_validate_str(&'a self) -> Option<Cow<'a, str>> {
Some(Cow::Borrowed(self))
}
}
impl<'a, T> AsValidateStr<'a> for Option<T>
where
T: AsValidateStr<'a>,
{
fn as_validate_str(&'a self) -> Option<Cow<'a, str>> {
match self {
None => None,
Some(v) => v.as_validate_str(),
}
}
}