Skip to content

Commit

Permalink
feat: remove duplicate rules
Browse files Browse the repository at this point in the history
in `merge()` and `and()` of RuleList
  • Loading branch information
asuper0 committed Sep 22, 2023
1 parent e908293 commit 33a4f8b
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 8 deletions.
33 changes: 27 additions & 6 deletions src/register/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ mod tests {

#[cfg(feature = "full")]
#[test]
fn repect_insert_rules() {
fn repeat_insert_rules() {
use crate::{
available::{Range, Required, Trim},
RuleExt,
Expand All @@ -573,32 +573,53 @@ mod tests {
.rule("foo", Range::new(1..2));

let vec = validate.rules.get(&FieldNames::new("foo".into())).unwrap();
assert!(vec.len() == 2);
assert_eq!(vec.len(), 2);
assert!(vec.is_bail() == false);

let validate = Validator::new()
.rule("foo", Required.and(Trim).bail())
.rule("foo", Range::new(1..2));

let vec = validate.rules.get(&FieldNames::new("foo".into())).unwrap();
assert!(vec.len() == 3);
assert_eq!(vec.len(), 3);
assert!(vec.is_bail() == true);

let validate = Validator::new()
.rule("foo", Required)
.rule("foo", Range::new(1..2).and(Trim).bail());

let vec = validate.rules.get(&FieldNames::new("foo".into())).unwrap();
assert!(vec.len() == 3);
assert_eq!(vec.len(), 3);
assert!(vec.is_bail() == true);

let validate = Validator::new()
.rule("foo", Required.and(Trim).bail())
.rule("foo", Range::new(1..2).and(Trim).bail());

// TODO need remove duplicates
let vec = validate.rules.get(&FieldNames::new("foo".into())).unwrap();
assert!(vec.len() == 4);
assert_eq!(vec.len(), 3);
assert!(vec.is_bail() == true);

let validate = Validator::new()
.rule("foo", Required.and(Trim).and(Required).bail())
.rule("foo", Range::new(1..2).and(Trim).and(Required).bail());

let vec = validate.rules.get(&FieldNames::new("foo".into())).unwrap();
assert_eq!(vec.len(), 3);
assert!(vec.is_bail() == true);

let validate = Validator::new()
.rule("foo", Required.and(Trim).and(Required).bail())
.rule("bar", Required.and(Trim).and(Required).bail())
.rule("foo", Range::new(1..2).and(Trim).and(Required).bail())
.rule("bar", Range::new(1..2).and(Trim).and(Required).bail());

let vec = validate.rules.get(&FieldNames::new("foo".into())).unwrap();
assert_eq!(vec.len(), 3);
assert!(vec.is_bail() == true);

let vec = validate.rules.get(&FieldNames::new("bar".into())).unwrap();
assert_eq!(vec.len(), 3);
assert!(vec.is_bail() == true);
}
}
53 changes: 51 additions & 2 deletions src/rule/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,22 @@ where
where
R2: Rule<(), Message = M>,
{
let is_dup = {
if self.name() != other.name() {
false
} else {
match self.name() {
"custom" => false,
_ => true,
}
}
};
RuleList {
list: vec![ErasedRule::<M>::new(self), ErasedRule::new(other)],
list: if is_dup {
vec![ErasedRule::new(other)]
} else {
vec![ErasedRule::<M>::new(self), ErasedRule::new(other)]
},
..Default::default()
}
}
Expand Down Expand Up @@ -155,11 +169,42 @@ impl<M> RuleList<M>
where
M: 'static,
{
pub fn remove_duplicate(&mut self, other: &ErasedRule<M>) {
let name = other.name();

let duplicate_rules: Vec<usize> = self
.list
.iter()
.enumerate()
.filter(|(_index, exist_rule)| {
if exist_rule.name() != name {
return false;
}
match name {
"custom" => false,
_ => true,
}
})
.map(|(index, _)| index)
.rev()
.collect();

for index in duplicate_rules {
// Use `swap_remove` to get better performence because we don't
// mind the order of rule list. If the order should be kept in
// the future, please use `remove` instead of `swap_remove`.
self.list.swap_remove(index);
}
}

pub fn and<R>(mut self, other: R) -> Self
where
R: Rule<(), Message = M>,
{
self.list.push(ErasedRule::new(other));
let other = ErasedRule::new(other);
self.remove_duplicate(&other);

self.list.push(other);
self
}

Expand Down Expand Up @@ -196,6 +241,10 @@ where
}

pub(crate) fn merge(&mut self, other: &mut RuleList<M>) {
for new_rule in &other.list {
self.remove_duplicate(new_rule);
}

self.list.append(&mut other.list);
self.is_bail = self.is_bail || other.is_bail;
}
Expand Down

0 comments on commit 33a4f8b

Please sign in to comment.