Skip to content

Commit

Permalink
Fix broken support for nested validation with multiple errors (#321)
Browse files Browse the repository at this point in the history
Fixes #319.

Signed-off-by: Johannes Löthberg <johannes.loethberg@elokon.com>
  • Loading branch information
kyrias committed Apr 10, 2024
1 parent 43d24d3 commit fab9ced
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
19 changes: 9 additions & 10 deletions validator/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,16 @@ impl ValidationErrors {
) -> &mut ValidationErrors {
match child {
Ok(()) => self,
Err(errors) => {
for (_, e) in &errors.0 {
if matches!(e, ValidationErrorsKind::Field(..)) {
self.add_nested(
field,
ValidationErrorsKind::Struct(Box::new(errors.clone())),
);
} else {
self.add_nested(field, e.clone());
}
Err(mut errors) => {
// This is a bit of a hack to be able to support collections which return a
// `ValidationErrors` with a made-up `_tmp_validator` entry which we need to strip
// off.
if let Some(collection) = errors.0.remove("_tmp_validator") {
self.add_nested(field, collection);
} else {
self.add_nested(field, ValidationErrorsKind::Struct(Box::new(errors)));
}

self
}
}
Expand Down
42 changes: 42 additions & 0 deletions validator_derive_tests/tests/nested.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,48 @@ fn is_fine_with_nested_validations() {
assert!(root.validate().is_ok());
}

#[test]
fn fails_nested_validation_multiple_members() {
#[derive(Validate)]
struct Root<'a> {
#[validate(length(min = 5, max = 10))]
value: String,
#[validate(nested)]
a: &'a A,
}

#[derive(Validate)]
struct A {
#[validate(length(min = 5, max = 10))]
value1: String,
#[validate(length(min = 5, max = 10))]
value2: String,
}

let root = Root {
value: "valid".to_string(),
a: &A { value1: "invalid value".to_string(), value2: "invalid value".to_string() },
};

let error_kind = ValidationErrorsKind::Field(vec![{
let mut error = ValidationError::new("length");
error.add_param("min".into(), &5);
error.add_param("max".into(), &10);
error.add_param("value".into(), &"invalid value");
error
}]);
assert_eq!(
root.validate(),
Err(ValidationErrors(HashMap::from_iter([(
"a",
ValidationErrorsKind::Struct(Box::new(ValidationErrors(HashMap::from_iter([
("value1", error_kind.clone()),
("value2", error_kind),
]))))
)])))
);
}

#[test]
fn fails_nested_validation() {
#[derive(Validate)]
Expand Down

0 comments on commit fab9ced

Please sign in to comment.