use super::super::Predicate;
use super::string::NonEmpty;
impl<T: Send + Sync + 'static> Predicate<Vec<T>> for NonEmpty {
type Error = &'static str;
fn check(value: &Vec<T>) -> Result<(), Self::Error> {
if value.is_empty() {
Err("collection cannot be empty")
} else {
Ok(())
}
}
fn description() -> &'static str {
"non-empty collection"
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct MaxSize<const N: usize>;
impl<const N: usize, T: Send + Sync + 'static> Predicate<Vec<T>> for MaxSize<N> {
type Error = String;
fn check(value: &Vec<T>) -> Result<(), Self::Error> {
if value.len() <= N {
Ok(())
} else {
Err(format!(
"collection size {} exceeds maximum {}",
value.len(),
N
))
}
}
fn description() -> &'static str {
"collection with maximum size"
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct MinSize<const N: usize>;
impl<const N: usize, T: Send + Sync + 'static> Predicate<Vec<T>> for MinSize<N> {
type Error = String;
fn check(value: &Vec<T>) -> Result<(), Self::Error> {
if value.len() >= N {
Ok(())
} else {
Err(format!(
"collection size {} is less than minimum {}",
value.len(),
N
))
}
}
fn description() -> &'static str {
"collection with minimum size"
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::refined::Refined;
type NonEmptyVec = Refined<Vec<i32>, NonEmpty>;
type SmallVec = Refined<Vec<i32>, MaxSize<3>>;
type AtLeastTwo = Refined<Vec<i32>, MinSize<2>>;
#[test]
fn test_non_empty_vec_success() {
assert!(NonEmptyVec::new(vec![1]).is_ok());
assert!(NonEmptyVec::new(vec![1, 2, 3]).is_ok());
}
#[test]
fn test_non_empty_vec_failure() {
let result = NonEmptyVec::new(vec![]);
assert!(result.is_err());
assert_eq!(result.unwrap_err(), "collection cannot be empty");
}
#[test]
fn test_max_size_success() {
assert!(SmallVec::new(vec![]).is_ok());
assert!(SmallVec::new(vec![1]).is_ok());
assert!(SmallVec::new(vec![1, 2, 3]).is_ok()); }
#[test]
fn test_max_size_failure() {
let result = SmallVec::new(vec![1, 2, 3, 4]);
assert!(result.is_err());
assert!(result.unwrap_err().contains("exceeds maximum"));
}
#[test]
fn test_min_size_success() {
assert!(AtLeastTwo::new(vec![1, 2]).is_ok()); assert!(AtLeastTwo::new(vec![1, 2, 3]).is_ok());
}
#[test]
fn test_min_size_failure() {
assert!(AtLeastTwo::new(vec![]).is_err());
assert!(AtLeastTwo::new(vec![1]).is_err());
}
#[test]
fn test_descriptions() {
assert_eq!(
<NonEmpty as Predicate<Vec<i32>>>::description(),
"non-empty collection"
);
assert_eq!(
<MaxSize<3> as Predicate<Vec<i32>>>::description(),
"collection with maximum size"
);
assert_eq!(
<MinSize<2> as Predicate<Vec<i32>>>::description(),
"collection with minimum size"
);
}
}