aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--validator/src/validation/mod.rs2
-rw-r--r--validator_derive/src/lib.rs4
-rw-r--r--validator_derive/src/quoting.rs2
-rw-r--r--validator_derive/tests/required.rs44
5 files changed, 47 insertions, 8 deletions
diff --git a/README.md b/README.md
index 712efac..b55bebd 100644
--- a/README.md
+++ b/README.md
@@ -279,6 +279,9 @@ This validator doesn't take any arguments: `#[validate(non_control_character)]`;
### required
Tests whether the `Option<T>` field is `Some`;
+### required_nested
+Tests whether the `Option<T>` field is `Some` and performs validation as `nested` do;
+
## Struct level validation
Often, some error validation can only be applied when looking at the full struct, here's how it works here:
diff --git a/validator/src/validation/mod.rs b/validator/src/validation/mod.rs
index 0b460a8..a2111d7 100644
--- a/validator/src/validation/mod.rs
+++ b/validator/src/validation/mod.rs
@@ -47,6 +47,7 @@ pub enum Validator {
#[cfg(feature = "unic")]
NonControlCharacter,
Required,
+ RequiredNested,
}
impl Validator {
@@ -68,6 +69,7 @@ impl Validator {
#[cfg(feature = "unic")]
Validator::NonControlCharacter => "non_control_character",
Validator::Required => "required",
+ Validator::RequiredNested => "required_nested",
}
}
}
diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs
index 6f91ae8..3244679 100644
--- a/validator_derive/src/lib.rs
+++ b/validator_derive/src/lib.rs
@@ -290,6 +290,10 @@ fn find_validators_for_field(
"required" => {
validators.push(FieldValidation::new(Validator::Required));
}
+ "required_nested" => {
+ validators.push(FieldValidation::new(Validator::Required));
+ validators.push(FieldValidation::new(Validator::Nested));
+ }
_ => panic!("Unexpected validator: {:?}", name.get_ident()),
}
}
diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs
index 4c81037..a5af288 100644
--- a/validator_derive/src/quoting.rs
+++ b/validator_derive/src/quoting.rs
@@ -465,7 +465,7 @@ pub fn quote_field_validation(
Validator::NonControlCharacter => {
validations.push(quote_non_control_character_validation(&field_quoter, validation))
}
- Validator::Required => {
+ Validator::Required | Validator::RequiredNested => {
validations.push(quote_required_validation(&field_quoter, validation))
}
}
diff --git a/validator_derive/tests/required.rs b/validator_derive/tests/required.rs
index 2f02b1b..a073f28 100644
--- a/validator_derive/tests/required.rs
+++ b/validator_derive/tests/required.rs
@@ -4,28 +4,58 @@ extern crate validator_derive;
use serde::Serialize;
use validator::Validate;
-#[derive(Debug, Serialize)]
+#[derive(Serialize)]
struct ObjectRef {
id: i32,
name: String,
}
-#[derive(Debug, Validate)]
-struct TestStruct {
+#[derive(Serialize, Validate)]
+struct CheckedObjectRef {
+ #[validate(range(min = 1))]
+ id: i32,
+ #[validate(length(min = 1))]
+ name: String,
+}
+
+#[derive(Validate)]
+struct Required {
#[validate(required)]
val: Option<ObjectRef>,
}
+#[derive(Validate)]
+struct RequiredNested {
+ #[validate(required_nested)]
+ val: Option<CheckedObjectRef>,
+}
+
+#[test]
+fn can_validate_required() {
+ let s = Required { val: Some(ObjectRef { id: 0, name: String::new() }) };
+
+ assert!(s.validate().is_ok());
+}
+
#[test]
-fn can_validate_some() {
- let s = TestStruct { val: Some(ObjectRef { id: 0, name: String::new() }) };
+fn can_validate_required_nested() {
+ let s = RequiredNested {
+ val: Some(CheckedObjectRef { id: 1, name: String::from("Reference representation") }),
+ };
assert!(s.validate().is_ok());
}
#[test]
-fn none_fails_validate() {
- let s = TestStruct { val: None };
+fn none_fails_required() {
+ let s = Required { val: None };
+
+ assert!(s.validate().is_err());
+}
+
+#[test]
+fn none_fails_required_nested() {
+ let s = RequiredNested { val: None };
assert!(s.validate().is_err());
}