Skip to content

Commit 72bbd02

Browse files
committed
implement CountGreater
1 parent ddcb3df commit 72bbd02

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

src/rule/collection/count.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
mod equal;
2+
mod greater;
23

34
pub use equal::*;
5+
pub use greater::*;

src/rule/collection/count/greater.rs

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

0 commit comments

Comments
 (0)