diff --git a/src/rule/collection.rs b/src/rule/collection.rs index ee176f9..edc979a 100644 --- a/src/rule/collection.rs +++ b/src/rule/collection.rs @@ -4,6 +4,7 @@ mod head; mod index; mod init; mod last; +mod reverse; pub use exists::*; pub use for_all::*; @@ -11,3 +12,4 @@ pub use head::*; pub use index::*; pub use init::*; pub use last::*; +pub use reverse::*; diff --git a/src/rule/collection/last.rs b/src/rule/collection/last.rs index f081fb2..27f4efe 100644 --- a/src/rule/collection/last.rs +++ b/src/rule/collection/last.rs @@ -1,10 +1,6 @@ -mod collection; -mod string; - use std::collections::VecDeque; -use std::marker::PhantomData; -use crate::rule::Rule; +use crate::rule::{Index0Rule, ReverseRule, Rule}; use crate::Refined; /// A type that holds a value satisfying the `LastRule` @@ -20,9 +16,7 @@ pub type LastVecDeque = Refined>; pub type LastString = Refined>; /// Rule where the last element satisfies the condition -pub struct LastRule { - _phantom_data: PhantomData<(RULE, ITERABLE)>, -} +pub type LastRule = ReverseRule, ITERABLE>; /// Rule where the last element in the `Vec` satisfies the condition pub type LastVecRule = LastRule::Item>>; diff --git a/src/rule/collection/last/collection.rs b/src/rule/collection/last/collection.rs deleted file mode 100644 index 26ecb8e..0000000 --- a/src/rule/collection/last/collection.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::rule::{LastRule, Rule}; -use std::collections::VecDeque; - -impl Rule for LastRule> -where - RULE: Rule, -{ - type Item = Vec; - - fn validate(target: Self::Item) -> Result> { - let mut target = target.into_iter().collect::>(); - let last = target.pop_back(); - match last { - Some(item) => match RULE::validate(item) { - Ok(validated_item) => { - target.push_back(validated_item); - Ok(target.into_iter().collect()) - } - Err(e) => { - target.push_back(e.into_value()); - Err(crate::result::Error::new( - target.into_iter().collect(), - "Failed to validate the last item", - )) - } - }, - None => Err(crate::result::Error::new( - target.into_iter().collect(), - "Last item does not exist", - )), - } - } -} - -impl Rule for LastRule> -where - RULE: Rule, -{ - type Item = VecDeque; - - fn validate(target: Self::Item) -> Result> { - let mut target = target; - let last = target.pop_back(); - match last { - Some(item) => match RULE::validate(item) { - Ok(validated_item) => { - target.push_back(validated_item); - Ok(target) - } - Err(err) => { - target.push_back(err.into_value()); - Err(crate::result::Error::new( - target, - "Failed to validate the last item", - )) - } - }, - None => Err(crate::result::Error::new( - target, - "Last item does not exist", - )), - } - } -} diff --git a/src/rule/collection/last/string.rs b/src/rule/collection/last/string.rs deleted file mode 100644 index 393c28d..0000000 --- a/src/rule/collection/last/string.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::rule::{LastRule, Rule}; - -impl Rule for LastRule -where - RULE: Rule, -{ - type Item = String; - - fn validate(target: Self::Item) -> Result> { - match target.chars().last() { - Some(item) => match RULE::validate(item) { - Ok(_) => Ok(target), - Err(_) => Err(crate::result::Error::new( - target, - "Failed to validate the last item", - )), - }, - None => Err(crate::result::Error::new( - target, - "Last item does not exist", - )), - } - } -} - -impl<'a, RULE> Rule for LastRule -where - RULE: Rule, -{ - type Item = &'a str; - - fn validate(target: Self::Item) -> Result> { - match target.chars().last() { - Some(item) => match RULE::validate(item) { - Ok(_) => Ok(target), - Err(_) => Err(crate::result::Error::new( - target, - "Failed to validate the last item", - )), - }, - None => Err(crate::result::Error::new( - target, - "Last item does not exist", - )), - } - } -} diff --git a/src/rule/collection/reverse.rs b/src/rule/collection/reverse.rs new file mode 100644 index 0000000..64541c4 --- /dev/null +++ b/src/rule/collection/reverse.rs @@ -0,0 +1,25 @@ +mod collection; +mod string; + +use crate::rule::Rule; +use crate::Refined; +use std::collections::VecDeque; +use std::marker::PhantomData; + +pub type Reverse = Refined>; + +pub type ReverseVec = Refined>; + +pub type ReverseVecDeque = Refined>; + +pub type ReverseString = Refined>; + +pub struct ReverseRule { + _phantom_data: PhantomData<(RULE, ITERABLE)>, +} + +pub type ReverseVecRule = ReverseRule::Item>>; + +pub type ReverseVecDequeRule = ReverseRule::Item>>; + +pub type ReverseStringRule = ReverseRule; diff --git a/src/rule/collection/reverse/collection.rs b/src/rule/collection/reverse/collection.rs new file mode 100644 index 0000000..ea37091 --- /dev/null +++ b/src/rule/collection/reverse/collection.rs @@ -0,0 +1,31 @@ +use std::collections::VecDeque; + +use crate::result::Error; +use crate::rule::collection::reverse::ReverseRule; +use crate::rule::Rule; + +macro_rules! impl_reverse { + ($($t:ty),*) => { + $( + impl Rule for ReverseRule + where + RULE: Rule, + { + type Item = $t; + + fn validate(target: Self::Item) -> Result> { + match RULE::validate(target.into_iter().rev().collect()) { + Ok(value) => Ok(value.into_iter().rev().collect()), + Err(e) => { + let message = e.to_string(); + Err(Error::new(e.into_value().into_iter().rev().collect(), message)) + }, + } + } + } + )* + }; + () => {}; +} + +impl_reverse![Vec, VecDeque]; diff --git a/src/rule/collection/reverse/string.rs b/src/rule/collection/reverse/string.rs new file mode 100644 index 0000000..d483666 --- /dev/null +++ b/src/rule/collection/reverse/string.rs @@ -0,0 +1,21 @@ +use crate::rule::{ReverseRule, Rule}; + +impl Rule for ReverseRule +where + RULE: Rule, +{ + type Item = String; + + fn validate(target: Self::Item) -> Result> { + match RULE::validate(target.chars().rev().collect()) { + Ok(value) => Ok(value.chars().rev().collect()), + Err(e) => { + let message = e.to_string(); + Err(crate::result::Error::new( + e.into_value().chars().rev().collect(), + message, + )) + } + } + } +}