pub mod error;
pub mod validators;
pub use error::{Error, Location};
pub use validatron_derive::Validate;
pub type Result<T> = std::result::Result<T, Error>;
pub trait Validate {
fn validate(&self) -> Result<()>;
}
fn validate_seq<'a, I, T: 'a>(sequence: I) -> Result<()>
where
I: IntoIterator<Item = &'a T>,
T: Validate,
{
let mut eb = Error::build();
for (i, x) in sequence.into_iter().enumerate() {
eb.try_at_index(i, x.validate());
}
eb.build()
}
impl<T> Validate for Vec<T>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
validate_seq(self)
}
}
impl<T> Validate for std::collections::VecDeque<T>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
validate_seq(self)
}
}
impl<T> Validate for std::collections::LinkedList<T>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
validate_seq(self)
}
}
impl<K, V, S> Validate for std::collections::HashMap<K, V, S>
where
K: std::fmt::Display,
V: Validate,
{
fn validate(&self) -> Result<()> {
let mut eb = Error::build();
for (k, v) in self {
eb.try_at_named(k.to_string(), v.validate());
}
eb.build()
}
}
impl<K, V> Validate for std::collections::BTreeMap<K, V>
where
K: std::fmt::Display,
V: Validate,
{
fn validate(&self) -> Result<()> {
let mut eb = Error::build();
for (k, v) in self {
eb.try_at_named(k.to_string(), v.validate());
}
eb.build()
}
}
impl<T, S> Validate for std::collections::HashSet<T, S>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
validate_seq(self)
}
}
impl<T> Validate for std::collections::BTreeSet<T>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
validate_seq(self)
}
}
impl<T> Validate for std::collections::BinaryHeap<T>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
validate_seq(self)
}
}
#[cfg(feature = "use-indexmap")]
impl<K, V> Validate for indexmap::IndexMap<K, V>
where
K: std::fmt::Display,
V: Validate,
{
fn validate(&self) -> Result<()> {
let mut eb = Error::build();
for (k, v) in self {
eb.try_at_named(k.to_string(), v.validate());
}
eb.build()
}
}
#[cfg(feature = "use-indexmap")]
impl<T, S> Validate for indexmap::IndexSet<T, S>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
validate_seq(self)
}
}
impl<T> Validate for Option<T>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
validate_seq(self)
}
}
impl<T, E> Validate for std::result::Result<T, E>
where
T: Validate,
{
fn validate(&self) -> Result<()> {
if let Ok(value) = self {
value.validate()
} else {
Err(Error::new("value is an Error"))
}
}
}