Skip to content

Commit

Permalink
refactor: forall exists
Browse files Browse the repository at this point in the history
  • Loading branch information
tomoikey committed Sep 14, 2024
1 parent c7384d9 commit 4a721c5
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/rule/exists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use crate::rule::ForAllRule;
use crate::Refined;

/// A type that holds a value satisfying the `ExistsRule`
pub type Exists<RULE, T> = Refined<ExistsRule<RULE, T>>;
pub type Exists<RULE, ITERABLE> = Refined<ExistsRule<RULE, ITERABLE>>;

/// Rule where at least one data in the collection satisfies the condition
pub type ExistsRule<RULE, T> = Not<ForAllRule<Not<RULE>, T>>;
pub type ExistsRule<RULE, ITERABLE> = Not<ForAllRule<Not<RULE>, ITERABLE>>;

#[cfg(test)]
mod tests {
Expand Down
43 changes: 35 additions & 8 deletions src/rule/for_all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@ use crate::rule::Rule;
use crate::Refined;

/// A type that holds a value satisfying the `ForAllRule`
pub type ForAll<RULE, T> = Refined<ForAllRule<RULE, T>>;
pub type ForAll<RULE, ITERABLE> = Refined<ForAllRule<RULE, ITERABLE>>;

/// Rule where all the data in the collection satisfies the condition
pub struct ForAllRule<RULE, T> {
_phantom_data: PhantomData<(RULE, T)>,
pub struct ForAllRule<RULE, ITERABLE>
where
RULE: Rule,
{
_phantom_data: PhantomData<(RULE, ITERABLE)>,
}

impl<RULE, ITEM> Rule for ForAllRule<RULE, Vec<ITEM>>
impl<RULE, ITEM> Rule for ForAllRule<RULE, Vec<RULE::Item>>
where
RULE: Rule<Item = ITEM>,
{
type Item = Vec<ITEM>;
type Item = Vec<RULE::Item>;

fn validate(target: &Self::Item) -> Result<(), Error> {
if target.iter().all(|item| RULE::validate(item).is_ok()) {
Expand All @@ -34,18 +37,21 @@ where
type Item = String;

fn validate(target: &Self::Item) -> Result<(), Error> {
if target.chars().all(|c| RULE::validate(&c).is_ok()) {
if target.chars().all(|item| RULE::validate(&item).is_ok()) {
Ok(())
} else {
Err(Error::new("not all items satisfy the condition"))
Err(Error::new(format!(
"{target} does not satisfy the condition"
)))
}
}
}

#[cfg(test)]
mod tests {
use crate::result::Error;
use crate::rule::for_all::ForAll;
use crate::rule::NonEmptyStringRule;
use crate::rule::{NonEmptyStringRule, Rule};

#[test]
fn for_all_1() -> anyhow::Result<()> {
Expand All @@ -62,4 +68,25 @@ mod tests {
assert!(for_all_result.is_err());
Ok(())
}

#[test]
fn for_all_3() -> anyhow::Result<()> {
struct CharRule;
impl Rule for CharRule {
type Item = char;

fn validate(target: &Self::Item) -> Result<(), Error> {
if target.is_alphabetic() {
Ok(())
} else {
Err(Error::new(format!("{} is not an alphabet", target)))
}
}
}

let value = "hello".to_string();
let for_all: ForAll<CharRule, String> = ForAll::new(value.clone())?;
assert_eq!(for_all.into_value(), value);
Ok(())
}
}

0 comments on commit 4a721c5

Please sign in to comment.