From 72bbd0203dffe51c27a1661f835599f2003433b2 Mon Sep 17 00:00:00 2001 From: tomoikey <55743826+tomoikey@users.noreply.github.com> Date: Mon, 25 Nov 2024 21:54:57 +0900 Subject: [PATCH] implement CountGreater --- src/rule/collection/count.rs | 2 + src/rule/collection/count/greater.rs | 115 +++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/rule/collection/count/greater.rs diff --git a/src/rule/collection/count.rs b/src/rule/collection/count.rs index ba03765..f832097 100644 --- a/src/rule/collection/count.rs +++ b/src/rule/collection/count.rs @@ -1,3 +1,5 @@ mod equal; +mod greater; pub use equal::*; +pub use greater::*; diff --git a/src/rule/collection/count/greater.rs b/src/rule/collection/count/greater.rs new file mode 100644 index 0000000..85b02fb --- /dev/null +++ b/src/rule/collection/count/greater.rs @@ -0,0 +1,115 @@ +use crate::result::Error; +use crate::rule::{Iterable, Rule}; +use crate::Refined; +use std::collections::VecDeque; + +/// A type that holds a value where the count of items in the collection that satisfy the condition is greater than `N`. +pub type CountGreater = + Refined>; + +/// A type that holds a `Vec` value where the count of items that satisfy the condition is greater than `N`. +pub type CountGreaterVec = CountGreater::Item>>; + +/// A type that holds a `VecDeque` value where the count of items that satisfy the condition is greater than `N`. +pub type CountGreaterVecDeque = + CountGreater::Item>>; + +/// A type that holds a `HashMap` value where the count of items that satisfy the condition is greater than `N`. +pub type CountGreaterHashMap = + CountGreater::Item>>; + +/// A type that holds a `HashSet` value where the count of items that satisfy the condition is greater than `N`. +pub type CountGreaterHashSet = + CountGreater>; + +/// A type that holds a `String` value where the count of items that satisfy the condition is greater than `N`. +pub type CountGreaterString = CountGreater; + +/// A type that holds a `&'a str` value where the count of items that satisfy the condition is greater than `N`. +pub type CountGreaterStr<'a, const N: usize, RULE> = CountGreater; + +/// Rule where the count of items in the collection that satisfy the condition is greater than `N`. +pub struct CountGreaterRule +where + ITERABLE: Iterable, +{ + _phantom: std::marker::PhantomData<(RULE, ITERABLE)>, +} + +impl Rule for CountGreaterRule +where + ITERABLE: Iterable + FromIterator, + RULE: Rule, +{ + type Item = ITERABLE; + fn validate(target: Self::Item) -> crate::Result { + let mut count = 0; + let mut deque = VecDeque::new(); + for item in target.into_iterator() { + match RULE::validate(item) { + Ok(item) => { + deque.push_back(item); + count += 1 + } + Err(e) => { + deque.push_back(e.into_value()); + } + } + } + let target = ITERABLE::from_iter(deque); + if count > N { + Ok(target) + } else { + Err(Error::new( + target, + format!("count is not greater than {}, actual count is {}", N, count), + )) + } + } +} + +/// Rule where the count of items in the `Vec` that satisfy the condition is greater than `N`. +pub type CountGreaterVecRule = + CountGreaterRule::Item>>; + +/// Rule where the count of items in the `VecDeque` that satisfy the condition is greater than `N`. +pub type CountGreaterVecDequeRule = + CountGreaterRule::Item>>; + +/// Rule where the count of items in the `HashMap` that satisfy the condition is greater than `N`. +pub type CountGreaterHashMapRule = + CountGreaterRule::Item>>; + +/// Rule where the count of items in the `HashSet` that satisfy the condition is greater than `N`. +pub type CountGreaterHashSetRule = + CountGreaterRule>; + +/// Rule where the count of items in the `String` that satisfy the condition is greater than `N`. +pub type CountGreaterStringRule = CountGreaterRule; + +/// Rule where the count of items in the `&'a str` that satisfy the condition is greater than `N`. +pub type CountGreaterStrRule<'a, const N: usize, RULE> = CountGreaterRule; + +#[cfg(test)] +mod tests { + use crate::result::Error; + use crate::rule::{CountGreater, NonEmptyStringRule}; + + #[test] + fn count_greater_1() -> Result<(), Error>> { + let value = vec!["good morning".to_string(), "hello".to_string()]; + let count_greater: CountGreater<1, NonEmptyStringRule, Vec<_>> = + CountGreater::new(value.clone())?; + assert_eq!(count_greater.into_value(), value); + Ok(()) + } + + #[test] + fn count_greater_2() -> anyhow::Result<()> { + let value = vec!["".to_string(), "".to_string()]; + let count_greater_result = + CountGreater::<1, NonEmptyStringRule, Vec<_>>::new(value.clone()); + assert!(count_greater_result.is_err()); + Ok(()) + } +}