From 8e4a3767acff75b40367044efa33de162708e9ae Mon Sep 17 00:00:00 2001 From: timvisee Date: Thu, 31 Aug 2023 14:59:50 +0200 Subject: [PATCH] Start implementing range support for NonZero types --- validator_derive/src/asserts.rs | 35 ++++++++++++++++++- validator_derive/src/quoting.rs | 12 +++++-- validator_derive_tests/tests/range.rs | 15 ++++++++ .../tests/run-pass/range.rs | 14 ++++++++ 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/validator_derive/src/asserts.rs b/validator_derive/src/asserts.rs index 6c1b8b30..637b6f37 100644 --- a/validator_derive/src/asserts.rs +++ b/validator_derive/src/asserts.rs @@ -19,7 +19,7 @@ static CUSTOM_ARG_ALLOWED_COPY_TYPES: [&str; 14] = [ "f64", ]; -pub static NUMBER_TYPES: [&str; 38] = [ +pub static NUMBER_TYPES: [&str; 71] = [ "usize", "u8", "u16", @@ -34,6 +34,17 @@ pub static NUMBER_TYPES: [&str; 38] = [ "i128", "f32", "f64", + "NonZeroU8", + "NonZeroU16", + "NonZeroU32", + "NonZeroU64", + "NonZeroU128", + "NonZeroIsize", + "NonZeroI8", + "NonZeroI16", + "NonZeroI32", + "NonZeroI64", + "NonZeroI128", "Option", "Option", "Option", @@ -46,6 +57,17 @@ pub static NUMBER_TYPES: [&str; 38] = [ "Option", "Option", "Option", + "Option", + "Option", + "Option", + "Option", + "Option", + "Option", + "Option", + "Option", + "Option", + "Option", + "Option", "Option>", "Option>", "Option>", @@ -58,6 +80,17 @@ pub static NUMBER_TYPES: [&str; 38] = [ "Option>", "Option>", "Option>", + "Option>", + "Option>", + "Option>", + "Option>", + "Option>", + "Option>", + "Option>", + "Option>", + "Option>", + "Option>", + "Option>", ]; pub fn assert_string_type(name: &str, type_name: &str, field_type: &syn::Type) { diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs index 03e40a31..21214b5d 100644 --- a/validator_derive/src/quoting.rs +++ b/validator_derive/src/quoting.rs @@ -31,11 +31,19 @@ impl FieldQuoter { let ident = &self.ident; if self._type.starts_with("Option<") { - quote!(#ident) + if !self._type.contains("NonZero") { + quote!(#ident) + } else { + quote!(#ident.get()) + } } else if COW_TYPE.is_match(self._type.as_ref()) { quote!(self.#ident.as_ref()) } else if self._type.starts_with('&') || NUMBER_TYPES.contains(&self._type.as_ref()) { - quote!(self.#ident) + if !self._type.contains("NonZero") { + quote!(self.#ident) + } else { + quote!(self.#ident.get()) + } } else { quote!(&self.#ident) } diff --git a/validator_derive_tests/tests/range.rs b/validator_derive_tests/tests/range.rs index 7af240b0..bf204bac 100644 --- a/validator_derive_tests/tests/range.rs +++ b/validator_derive_tests/tests/range.rs @@ -1,3 +1,5 @@ +use std::num::NonZeroU64; + use validator::{Validate, ValidationErrors}; const MAX_CONST: usize = 10; @@ -23,6 +25,19 @@ fn can_validate_range_ok() { assert!(s.validate().is_ok()); } +#[test] +fn can_validate_range_non_zero_ok() { + #[derive(Debug, Validate)] + struct TestStruct { + #[validate(range(min = 5, max = 10))] + val: NonZeroU64, + } + + let s = TestStruct { val: NonZeroU64::new(6).unwrap() }; + + assert!(s.validate().is_ok()); +} + #[test] fn can_validate_only_min_ok() { #[derive(Debug, Validate)] diff --git a/validator_derive_tests/tests/run-pass/range.rs b/validator_derive_tests/tests/run-pass/range.rs index fda45ca0..92e8a693 100644 --- a/validator_derive_tests/tests/run-pass/range.rs +++ b/validator_derive_tests/tests/run-pass/range.rs @@ -1,5 +1,7 @@ use validator::Validate; +use std::num::{NonZeroI32, NonZeroI64, NonZeroU32, NonZeroU64}; + #[derive(Validate)] struct Test { #[validate(range(min = 1, max = 2.2))] @@ -24,6 +26,18 @@ struct Test { s10: Option, #[validate(range(max = 18.0))] s11: Option, + #[validate(range(min = 18, max = 22))] + s12: NonZeroI32, + #[validate(range(min = 18, max = 22))] + s13: NonZeroU32, + #[validate(range(min = 18.1, max = 22))] + s14: NonZeroI32, + #[validate(range(min = 18.1, max = 22))] + s15: NonZeroU32, + #[validate(range(min = 18, max = 22))] + s16: Option, + #[validate(range(min = 18, max = 22))] + s17: Option, } fn main() {}