aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--validator/src/lib.rs1
-rw-r--r--validator/src/validation/mod.rs3
-rw-r--r--validator/src/validation/required.rs5
-rw-r--r--validator_derive/src/lib.rs3
-rw-r--r--validator_derive/src/quoting.rs23
-rw-r--r--validator_derive/tests/required.rs31
7 files changed, 69 insertions, 0 deletions
diff --git a/README.md b/README.md
index 3c869e2..712efac 100644
--- a/README.md
+++ b/README.md
@@ -276,6 +276,9 @@ Tests whether the String has any utf-8 control caracters, fails validation if it
To use this validator, you must enable the `unic` feature for the `validator_derive` crate.
This validator doesn't take any arguments: `#[validate(non_control_character)]`;
+### required
+Tests whether the `Option<T>` field is `Some`;
+
## 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/lib.rs b/validator/src/lib.rs
index 5313c41..deaaca6 100644
--- a/validator/src/lib.rs
+++ b/validator/src/lib.rs
@@ -14,6 +14,7 @@ pub use validation::non_control_character::validate_non_control_character;
#[cfg(feature = "phone")]
pub use validation::phone::validate_phone;
pub use validation::range::validate_range;
+pub use validation::required::validate_required;
pub use validation::urls::validate_url;
pub use validation::Validator;
diff --git a/validator/src/validation/mod.rs b/validator/src/validation/mod.rs
index 1675730..0b460a8 100644
--- a/validator/src/validation/mod.rs
+++ b/validator/src/validation/mod.rs
@@ -10,6 +10,7 @@ pub mod non_control_character;
#[cfg(feature = "phone")]
pub mod phone;
pub mod range;
+pub mod required;
pub mod urls;
/// Contains all the validators that can be used
@@ -45,6 +46,7 @@ pub enum Validator {
Nested,
#[cfg(feature = "unic")]
NonControlCharacter,
+ Required,
}
impl Validator {
@@ -65,6 +67,7 @@ impl Validator {
Validator::Nested => "nested",
#[cfg(feature = "unic")]
Validator::NonControlCharacter => "non_control_character",
+ Validator::Required => "required",
}
}
}
diff --git a/validator/src/validation/required.rs b/validator/src/validation/required.rs
new file mode 100644
index 0000000..80b06b0
--- /dev/null
+++ b/validator/src/validation/required.rs
@@ -0,0 +1,5 @@
+/// Validates whether the given Option is Some
+#[must_use]
+pub fn validate_required<T>(val: &Option<T>) -> bool {
+ val.is_some()
+}
diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs
index 6f74202..6f91ae8 100644
--- a/validator_derive/src/lib.rs
+++ b/validator_derive/src/lib.rs
@@ -287,6 +287,9 @@ fn find_validators_for_field(
Validator::NonControlCharacter,
));
}
+ "required" => {
+ validators.push(FieldValidation::new(Validator::Required));
+ }
_ => panic!("Unexpected validator: {:?}", name.get_ident()),
}
}
diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs
index dc466ac..4c81037 100644
--- a/validator_derive/src/quoting.rs
+++ b/validator_derive/src/quoting.rs
@@ -465,6 +465,9 @@ pub fn quote_field_validation(
Validator::NonControlCharacter => {
validations.push(quote_non_control_character_validation(&field_quoter, validation))
}
+ Validator::Required => {
+ validations.push(quote_required_validation(&field_quoter, validation))
+ }
}
}
@@ -501,3 +504,23 @@ pub fn quote_schema_validation(validation: Option<SchemaValidation>) -> proc_mac
quote!()
}
}
+
+pub fn quote_required_validation(
+ field_quoter: &FieldQuoter,
+ validation: &FieldValidation,
+) -> proc_macro2::TokenStream {
+ let field_name = &field_quoter.name;
+ let ident = &field_quoter.ident;
+ let validator_param = quote!(&self.#ident);
+
+ let quoted_error = quote_error(&validation);
+ let quoted = quote!(
+ if !::validator::validate_required(#validator_param) {
+ #quoted_error
+ err.add_param(::std::borrow::Cow::from("value"), &#validator_param);
+ errors.add(#field_name, err);
+ }
+ );
+
+ quoted
+}
diff --git a/validator_derive/tests/required.rs b/validator_derive/tests/required.rs
new file mode 100644
index 0000000..2f02b1b
--- /dev/null
+++ b/validator_derive/tests/required.rs
@@ -0,0 +1,31 @@
+#[macro_use]
+extern crate validator_derive;
+
+use serde::Serialize;
+use validator::Validate;
+
+#[derive(Debug, Serialize)]
+struct ObjectRef {
+ id: i32,
+ name: String,
+}
+
+#[derive(Debug, Validate)]
+struct TestStruct {
+ #[validate(required)]
+ val: Option<ObjectRef>,
+}
+
+#[test]
+fn can_validate_some() {
+ let s = TestStruct { val: Some(ObjectRef { id: 0, name: String::new() }) };
+
+ assert!(s.validate().is_ok());
+}
+
+#[test]
+fn none_fails_validate() {
+ let s = TestStruct { val: None };
+
+ assert!(s.validate().is_err());
+}