Skip to content

Commit

Permalink
fix: forall
Browse files Browse the repository at this point in the history
  • Loading branch information
tomoikey committed Sep 14, 2024
1 parent 4a721c5 commit 4a8bb6a
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 38 deletions.
3 changes: 1 addition & 2 deletions src/refined.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{Display, Formatter};
use std::marker::PhantomData;

use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::result::Error;
use crate::rule::Rule;

Expand Down
4 changes: 2 additions & 2 deletions src/rule/exists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ mod tests {
#[test]
fn exists_1() -> anyhow::Result<()> {
let value = vec!["good morning".to_string(), "hello".to_string()];
let exists: Exists<NonEmptyStringRule, _> = Exists::new(value.clone())?;
let exists: Exists<NonEmptyStringRule, Vec<_>> = Exists::new(value.clone())?;
assert_eq!(exists.into_value(), value);
Ok(())
}

#[test]
fn exists_2() -> anyhow::Result<()> {
let value = vec!["".to_string(), "".to_string()];
let exists_result = Exists::<NonEmptyStringRule, _>::new(value.clone());
let exists_result = Exists::<NonEmptyStringRule, Vec<_>>::new(value.clone());
assert!(exists_result.is_err());
Ok(())
}
Expand Down
54 changes: 24 additions & 30 deletions src/rule/for_all.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
mod string;

use std::collections::{HashSet, VecDeque};
use std::marker::PhantomData;

use crate::result::Error;
Expand All @@ -15,37 +18,28 @@ where
_phantom_data: PhantomData<(RULE, ITERABLE)>,
}

impl<RULE, ITEM> Rule for ForAllRule<RULE, Vec<RULE::Item>>
where
RULE: Rule<Item = ITEM>,
{
type Item = Vec<RULE::Item>;
macro_rules! impl_for_all {
($($t:ty),*) => {
$(
impl<RULE> Rule for ForAllRule<RULE, $t>
where
RULE: Rule,
{
type Item = $t;

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

impl<RULE> Rule for ForAllRule<RULE, String>
where
RULE: Rule<Item = char>,
{
type Item = String;

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

#[cfg(test)]
mod tests {
Expand All @@ -56,15 +50,15 @@ mod tests {
#[test]
fn for_all_1() -> anyhow::Result<()> {
let value = vec!["good morning".to_string(), "hello".to_string()];
let for_all: ForAll<NonEmptyStringRule, _> = ForAll::new(value.clone())?;
let for_all: ForAll<NonEmptyStringRule, Vec<_>> = ForAll::new(value.clone())?;
assert_eq!(for_all.into_value(), value);
Ok(())
}

#[test]
fn for_all_2() -> anyhow::Result<()> {
let value = vec!["good morning".to_string(), "".to_string()];
let for_all_result = ForAll::<NonEmptyStringRule, _>::new(value.clone());
let for_all_result = ForAll::<NonEmptyStringRule, Vec<_>>::new(value.clone());
assert!(for_all_result.is_err());
Ok(())
}
Expand Down
36 changes: 36 additions & 0 deletions src/rule/for_all/string.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use crate::result::Error;
use crate::rule::{ForAllRule, Rule};

impl<RULE> Rule for ForAllRule<RULE, String>
where
RULE: Rule<Item = char>,
{
type Item = String;

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

impl<RULE> Rule for ForAllRule<RULE, &'static str>
where
RULE: Rule<Item = char>,
{
type Item = &'static str;

fn validate(target: &Self::Item) -> Result<(), Error> {
if target.chars().all(|item| RULE::validate(&item).is_ok()) {
Ok(())
} else {
Err(Error::new(format!(
"{target} does not satisfy the condition"
)))
}
}
}
8 changes: 4 additions & 4 deletions tests/read_me.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,23 +269,23 @@ type TargetAgeRule = And<TargetAge18OrMore, TargetAge80OrLess>;
#[test]
fn example_11() -> anyhow::Result<()> {
let vec = vec!["Hello".to_string(), "World".to_string()];
let for_all_ok = ForAll::<NonEmptyStringRule, _>::new(vec.clone())?;
let for_all_ok = ForAll::<NonEmptyStringRule, Vec<_>>::new(vec.clone())?;
assert_eq!(vec, for_all_ok.into_value());

let vec = vec!["Hello".to_string(), "".to_string()];
let for_all_err = ForAll::<NonEmptyStringRule, _>::new(vec.clone());
let for_all_err = ForAll::<NonEmptyStringRule, Vec<_>>::new(vec.clone());
assert!(for_all_err.is_err());
Ok(())
}

#[test]
fn example_12() -> anyhow::Result<()> {
let vec = vec!["Hello".to_string(), "".to_string()];
let exists_ok = Exists::<NonEmptyStringRule, _>::new(vec.clone())?;
let exists_ok = Exists::<NonEmptyStringRule, Vec<_>>::new(vec.clone())?;
assert_eq!(vec, exists_ok.into_value());

let vec = vec!["".to_string(), "".to_string()];
let exists_err = Exists::<NonEmptyStringRule, _>::new(vec.clone());
let exists_err = Exists::<NonEmptyStringRule, Vec<_>>::new(vec.clone());
assert!(exists_err.is_err());
Ok(())
}
Expand Down

0 comments on commit 4a8bb6a

Please sign in to comment.