Skip to content

Commit 9a2a813

Browse files
committed
implement CountLess
1 parent 72bbd02 commit 9a2a813

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

src/rule/collection/count.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
mod equal;
22
mod greater;
3+
mod less;
34

45
pub use equal::*;
56
pub use greater::*;
7+
pub use less::*;

src/rule/collection/count/less.rs

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use crate::result::Error;
2+
use crate::rule::{Iterable, Rule};
3+
use crate::Refined;
4+
use std::collections::VecDeque;
5+
6+
/// A type that holds a value where the count of items in the collection that satisfy the condition is less than `N`.
7+
pub type CountLess<const N: usize, RULE, ITERABLE> = Refined<CountLessRule<N, RULE, ITERABLE>>;
8+
9+
/// A type that holds a `Vec` value where the count of items that satisfy the condition is less than `N`.
10+
pub type CountLessVec<const N: usize, RULE> = CountLess<N, RULE, Vec<<RULE as Rule>::Item>>;
11+
12+
/// A type that holds a `VecDeque` value where the count of items that satisfy the condition is less than `N`.
13+
pub type CountLessVecDeque<const N: usize, RULE> =
14+
CountLess<N, RULE, VecDeque<<RULE as Rule>::Item>>;
15+
16+
/// A type that holds a `HashMap` value where the count of items that satisfy the condition is less than `N`.
17+
pub type CountLessHashMap<const N: usize, RULE, K> =
18+
CountLess<N, RULE, std::collections::HashMap<K, <RULE as Rule>::Item>>;
19+
20+
/// A type that holds a `HashSet` value where the count of items that satisfy the condition is less than `N`.
21+
pub type CountLessHashSet<const N: usize, RULE, K> =
22+
CountLess<N, RULE, std::collections::HashSet<K>>;
23+
24+
/// A type that holds a `String` value where the count of items that satisfy the condition is less than `N`.
25+
pub type CountLessString<const N: usize, RULE> = CountLess<N, RULE, String>;
26+
27+
/// A type that holds a `&'a str` value where the count of items that satisfy the condition is less than `N`.
28+
pub type CountLessStr<'a, const N: usize, RULE> = CountLess<N, RULE, &'a str>;
29+
30+
/// Rule where the count of items in the collection that satisfy the condition is less than `N`.
31+
pub struct CountLessRule<const N: usize, RULE: Rule, ITERABLE: Iterable>
32+
where
33+
ITERABLE: Iterable<Item = RULE::Item>,
34+
{
35+
_phantom: std::marker::PhantomData<(RULE, ITERABLE)>,
36+
}
37+
38+
impl<const N: usize, ITERABLE, RULE> Rule for CountLessRule<N, RULE, ITERABLE>
39+
where
40+
ITERABLE: Iterable<Item = RULE::Item> + FromIterator<ITERABLE::Item>,
41+
RULE: Rule,
42+
{
43+
type Item = ITERABLE;
44+
fn validate(target: Self::Item) -> crate::Result<Self::Item> {
45+
let mut count = 0;
46+
let mut deque = VecDeque::new();
47+
for item in target.into_iterator() {
48+
match RULE::validate(item) {
49+
Ok(item) => {
50+
deque.push_back(item);
51+
count += 1
52+
}
53+
Err(e) => {
54+
deque.push_back(e.into_value());
55+
}
56+
}
57+
}
58+
let target = ITERABLE::from_iter(deque);
59+
if count < N {
60+
Ok(target)
61+
} else {
62+
Err(Error::new(
63+
target,
64+
format!("count is not less than {}, actual count is {}", N, count),
65+
))
66+
}
67+
}
68+
}
69+
70+
/// Rule where the count of items in the `Vec` that satisfy the condition is less than `N`.
71+
pub type CountLessVecRule<const N: usize, RULE> = CountLessRule<N, RULE, Vec<<RULE as Rule>::Item>>;
72+
73+
/// Rule where the count of items in the `VecDeque` that satisfy the condition is less than `N`.
74+
pub type CountLessVecDequeRule<const N: usize, RULE> =
75+
CountLessRule<N, RULE, VecDeque<<RULE as Rule>::Item>>;
76+
77+
/// Rule where the count of items in the `HashMap` that satisfy the condition is less than `N`.
78+
pub type CountLessHashMapRule<const N: usize, RULE, K> =
79+
CountLessRule<N, RULE, std::collections::HashMap<K, <RULE as Rule>::Item>>;
80+
81+
/// Rule where the count of items in the `HashSet` that satisfy the condition is less than `N`.
82+
pub type CountLessHashSetRule<const N: usize, RULE, K> =
83+
CountLessRule<N, RULE, std::collections::HashSet<K>>;
84+
85+
/// Rule where the count of items in the `String` that satisfy the condition is less than `N`.
86+
pub type CountLessStringRule<const N: usize, RULE> = CountLessRule<N, RULE, String>;
87+
88+
/// Rule where the count of items in the `&'a str` that satisfy the condition is less than `N`.
89+
pub type CountLessStrRule<'a, const N: usize, RULE> = CountLessRule<N, RULE, &'a str>;
90+
91+
#[cfg(test)]
92+
mod tests {
93+
use crate::result::Error;
94+
use crate::rule::{CountLess, NonEmptyStringRule};
95+
96+
#[test]
97+
fn count_less_1() -> Result<(), Error<Vec<String>>> {
98+
let value = vec!["good morning".to_string(), "hello".to_string()];
99+
let count_less: CountLess<3, NonEmptyStringRule, Vec<_>> = CountLess::new(value.clone())?;
100+
assert_eq!(count_less.into_value(), value);
101+
Ok(())
102+
}
103+
104+
#[test]
105+
fn count_less_2() -> anyhow::Result<()> {
106+
let value = vec!["".to_string(), "hello".to_string()];
107+
let count_less_result = CountLess::<1, NonEmptyStringRule, Vec<_>>::new(value.clone());
108+
assert!(count_less_result.is_err());
109+
Ok(())
110+
}
111+
}

0 commit comments

Comments
 (0)