diff --git a/README.md b/README.md index ab886a7..555e812 100644 --- a/README.md +++ b/README.md @@ -135,9 +135,11 @@ By using Rule Composer, composite rules can be easily created. `And` Rule Composer is a rule that satisfies both of the two rules. It is generally effective when you want to narrow down the condition range. + ```rust type Target = Refined]>; ``` + ```rust fn and_example() -> Result<(), Error> { let target = Target::new(50)?; @@ -158,6 +160,7 @@ It is generally effective when you want to expand the condition range. ```rust type Target = Refined, GreaterRuleU8<50>]>; ``` + ```rust fn or_example() -> Result<(), Error> { let target = Target::new(5)?; @@ -184,6 +187,7 @@ It is generally effective when you want to discard only certain situations. ```rust type Target = Refined>>; ``` + ```rust fn not_example() -> Result<(), Error> { let target = Target::new(49)?; @@ -225,7 +229,8 @@ fn if_example() -> Result<(), Error> { ### 5: `IfElse` Rule Composer -`IfElse` Rule Composer is a rule that applies a specific rule when a certain condition is met and another rule when it is not met. +`IfElse` Rule Composer is a rule that applies a specific rule when a certain condition is met and another rule when it +is not met. ```rust type Target = Refined, EvenRuleI8, OddRuleI8>>; @@ -396,7 +401,6 @@ fn range_example() -> Result<(), Error> { } ``` - # Iterator `refined_type` has several useful refined types for Iterators. @@ -555,9 +559,121 @@ fn example_17() -> anyhow::Result<()> { } ``` +## `CountEqual` + +`CountEqual` is a type that signifies the number of elements that satisfy the rule is a specific number. + +```rust +fn count_equal_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], false), + (vec!["good morning".to_string(), "".to_string()], true), + (vec!["".to_string(), "hello".to_string()], true), + (vec!["".to_string(), "".to_string()], false), + ]; + + for (value, expected) in table { + let refined = CountEqualVec::<1, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} +``` + +## `CountLess` + +`CountLess` is a type that signifies the number of elements that satisfy the rule is less than a specific number. + +```rust +fn count_less_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], false), + (vec!["good morning".to_string(), "".to_string()], true), + (vec!["".to_string(), "hello".to_string()], true), + (vec!["".to_string(), "".to_string()], true), + ]; + + for (value, expected) in table { + let refined = CountLessVec::<2, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} +``` + +## `CountGreater` + +`CountGreater` is a type that signifies the number of elements that satisfy the rule is greater than a specific number. + +```rust +fn count_greater_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], true), + (vec!["good morning".to_string(), "".to_string()], false), + (vec!["".to_string(), "hello".to_string()], false), + (vec!["".to_string(), "".to_string()], false), + ]; + + for (value, expected) in table { + let refined = CountGreaterVec::<1, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} +``` + +## `CountLessEqual` + +`CountLessEqual` is a type that signifies the number of elements that satisfy the rule is less than or equal to a +specific number. + +```rust +fn count_less_equal_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], true), + (vec!["good morning".to_string(), "".to_string()], true), + (vec!["".to_string(), "hello".to_string()], true), + (vec!["".to_string(), "".to_string()], true), + ]; + + for (value, expected) in table { + let refined = CountLessEqualVec::<2, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} +``` + +## `CountGreaterEqual` + +`CountGreaterEqual` is a type that signifies the number of elements that satisfy the rule is greater than or equal to a +specific number. + +```rust +fn count_greater_equal_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], true), + (vec!["good morning".to_string(), "".to_string()], true), + (vec!["".to_string(), "hello".to_string()], true), + (vec!["".to_string(), "".to_string()], false), + ]; + + for (value, expected) in table { + let refined = CountGreaterEqualVec::<1, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} +``` + ## `Reverse` -`Reverse` is a rule that applies a specific rule to all elements in the Iterator in reverse order. +`Reverse` is a rule that applies a specific rule to all elements in the Iterator in reverse order. ```rust fn example_18() -> Result<(), Error>> { @@ -625,6 +741,7 @@ impl SkipOption for NoSkip { You can impose constraints on objects that have a length, such as `String` or `Vec`. ## `LengthMinMax` + `LengthMinMax` is a type that signifies the target has a length between a certain number and another number. ```rust @@ -645,6 +762,7 @@ fn length_min_max_example() -> Result<(), Error> { ``` ## `LengthGreater` + `LengthGreater` is a type that signifies the target has a length greater than a certain number. ```rust @@ -662,6 +780,7 @@ fn length_greater_example() -> Result<(), Error> { ``` ## `LengthLess` + `LengthLess` is a type that signifies the target has a length less than a certain number. ```rust @@ -679,6 +798,7 @@ fn length_less_example() -> Result<(), Error> { ``` ## `LengthEqual` + `LengthEqual` is a type that signifies the target has a length equal to a certain number. ```rust diff --git a/tests/read_me.rs b/tests/read_me.rs index e7de9f8..4c982c5 100644 --- a/tests/read_me.rs +++ b/tests/read_me.rs @@ -4,8 +4,9 @@ use serde_json::json; use refined_type::result::Error; use refined_type::rule::composer::{If, IfElse, Not}; use refined_type::rule::{ - EqualU8, EvenRuleI8, ExistsVec, ForAllVec, GreaterEqualRuleI8, GreaterEqualU8, GreaterU8, - HeadVec, IndexRuleVec, IndexVec, InitVec, LastVec, LengthDefinition, LengthEqual, + CountEqualVec, CountGreaterEqualVec, CountGreaterVec, CountLessEqualVec, + CountLessVec, EqualU8, EvenRuleI8, ExistsVec, ForAllVec, GreaterEqualRuleI8, GreaterEqualU8, + GreaterU8, HeadVec, IndexRuleVec, IndexVec, InitVec, LastVec, LengthDefinition, LengthEqual, LengthEqualRule, LengthGreater, LengthLess, LengthMinMax, LessEqualU8, LessU8, MinMaxU8, NonEmptyString, NonEmptyStringRule, NonEmptyVec, NonEmptyVecDeque, OddRuleI8, RangeU8, Reverse, Rule, SkipFirst, SkipVec, TailVec, @@ -525,6 +526,91 @@ fn example_17() -> anyhow::Result<()> { Ok(()) } +#[test] +fn count_equal_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], false), + (vec!["good morning".to_string(), "".to_string()], true), + (vec!["".to_string(), "hello".to_string()], true), + (vec!["".to_string(), "".to_string()], false), + ]; + + for (value, expected) in table { + let refined = CountEqualVec::<1, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} + +#[test] +fn count_less_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], false), + (vec!["good morning".to_string(), "".to_string()], true), + (vec!["".to_string(), "hello".to_string()], true), + (vec!["".to_string(), "".to_string()], true), + ]; + + for (value, expected) in table { + let refined = CountLessVec::<2, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} + +#[test] +fn count_greater_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], true), + (vec!["good morning".to_string(), "".to_string()], false), + (vec!["".to_string(), "hello".to_string()], false), + (vec!["".to_string(), "".to_string()], false), + ]; + + for (value, expected) in table { + let refined = CountGreaterVec::<1, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} + +#[test] +fn count_less_equal_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], true), + (vec!["good morning".to_string(), "".to_string()], true), + (vec!["".to_string(), "hello".to_string()], true), + (vec!["".to_string(), "".to_string()], true), + ]; + + for (value, expected) in table { + let refined = CountLessEqualVec::<2, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} + +#[test] +fn count_greater_equal_example() -> Result<(), Error>> { + let table = vec![ + (vec!["good morning".to_string(), "hello".to_string()], true), + (vec!["good morning".to_string(), "".to_string()], true), + (vec!["".to_string(), "hello".to_string()], true), + (vec!["".to_string(), "".to_string()], false), + ]; + + for (value, expected) in table { + let refined = CountGreaterEqualVec::<1, NonEmptyStringRule>::new(value.clone()); + assert_eq!(refined.is_ok(), expected); + } + + Ok(()) +} + #[test] fn example_18() -> Result<(), Error>> { let table = vec![