|
| 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