diff --git a/crates/serde_valid/src/error.rs b/crates/serde_valid/src/error.rs index 92cae6c..c25787a 100644 --- a/crates/serde_valid/src/error.rs +++ b/crates/serde_valid/src/error.rs @@ -243,3 +243,6 @@ struct_error_params!( pub candidates: Vec, } ); + +#[deprecated(since = "2.0.2", note = "use `EnumError` instead")] +pub type EnumerateError = EnumError; diff --git a/crates/serde_valid/src/lib.rs b/crates/serde_valid/src/lib.rs index 3708c1d..ed0eaf9 100644 --- a/crates/serde_valid/src/lib.rs +++ b/crates/serde_valid/src/lib.rs @@ -578,6 +578,8 @@ mod traits; pub mod utils; pub mod validation; +#[allow(deprecated)] +pub use error::EnumerateError; pub use error::{ EnumError, Error, ExclusiveMaximumError, ExclusiveMinimumError, MaxItemsError, MaxLengthError, MaxPropertiesError, MaximumError, MinItemsError, MinLengthError, MinPropertiesError, @@ -587,6 +589,8 @@ pub use error::{ pub use features::*; use indexmap::IndexMap; use std::{borrow::Cow, collections::HashMap}; +#[allow(deprecated)] +pub use validation::ValidateEnumerate; pub use validation::{ ValidateEnum, ValidateExclusiveMaximum, ValidateExclusiveMinimum, ValidateMaxItems, ValidateMaxLength, ValidateMaxProperties, ValidateMaximum, ValidateMinItems, ValidateMinLength, diff --git a/crates/serde_valid/src/validation.rs b/crates/serde_valid/src/validation.rs index ce88f91..c980ddb 100644 --- a/crates/serde_valid/src/validation.rs +++ b/crates/serde_valid/src/validation.rs @@ -19,6 +19,8 @@ pub use error::{ PropertyErrorsMap, PropertyVecErrorsMap, VecErrors, }; pub use generic::ValidateEnum; +#[allow(deprecated)] +pub use generic::ValidateEnumerate; use indexmap::IndexMap; pub use numeric::{ ValidateExclusiveMaximum, ValidateExclusiveMinimum, ValidateMaximum, ValidateMinimum, @@ -178,6 +180,7 @@ macro_rules! impl_composited_validation_1args { } }; ( + $(#[$trait_meta:meta])+ pub trait $ValidateCompositedTrait:ident { fn $validate_composited_method:ident( &self, @@ -185,6 +188,50 @@ macro_rules! impl_composited_validation_1args { ) -> Result<(), Composited<$Error:ty>>; } ) => { + impl_composited_validation_1args!( + @generic + [#[allow(deprecated)] $(#[$trait_meta])*] + [#[allow(deprecated)]] + pub trait $ValidateCompositedTrait { + fn $validate_composited_method( + &self, + $limit: T, + ) -> Result<(), Composited<$Error>>; + } + ); + }; + ( + pub trait $ValidateCompositedTrait:ident { + fn $validate_composited_method:ident( + &self, + $limit:ident: T$(,)* + ) -> Result<(), Composited<$Error:ty>>; + } + ) => { + impl_composited_validation_1args!( + @generic + [] + [] + pub trait $ValidateCompositedTrait { + fn $validate_composited_method( + &self, + $limit: T, + ) -> Result<(), Composited<$Error>>; + } + ); + }; + ( + @generic + [$(#[$trait_meta:meta])*] + [$(#[$impl_meta:meta])*] + pub trait $ValidateCompositedTrait:ident { + fn $validate_composited_method:ident( + &self, + $limit:ident: T$(,)* + ) -> Result<(), Composited<$Error:ty>>; + } + ) => { + $(#[$trait_meta])* pub trait $ValidateCompositedTrait { fn $validate_composited_method( &self, @@ -192,6 +239,7 @@ macro_rules! impl_composited_validation_1args { ) -> Result<(), crate::validation::Composited<$Error>>; } + $(#[$impl_meta])* impl $ValidateCompositedTrait for Vec where T: Copy, @@ -220,6 +268,7 @@ macro_rules! impl_composited_validation_1args { } } + $(#[$impl_meta])* impl $ValidateCompositedTrait for std::collections::HashMap where T: Copy, @@ -245,6 +294,7 @@ macro_rules! impl_composited_validation_1args { } } + $(#[$impl_meta])* impl $ValidateCompositedTrait for [U; N] where T: Copy, @@ -273,6 +323,7 @@ macro_rules! impl_composited_validation_1args { } } + $(#[$impl_meta])* impl $ValidateCompositedTrait for Option where T: Copy, @@ -427,3 +478,13 @@ impl_composited_validation_1args!( fn validate_composited_enum(&self, candidates: T) -> Result<(), Composited>; } ); + +impl_composited_validation_1args!( + #[deprecated( + since = "2.0.2", + note = "use `ValidateCompositedEnum` and `validate_composited_enum` instead" + )] + pub trait ValidateCompositedEnumerate { + fn validate_composited_enumerate(&self, enumerate: T) -> Result<(), Composited>; + } +); diff --git a/crates/serde_valid/src/validation/error.rs b/crates/serde_valid/src/validation/error.rs index 30b0df5..6b4cd48 100644 --- a/crates/serde_valid/src/validation/error.rs +++ b/crates/serde_valid/src/validation/error.rs @@ -7,6 +7,8 @@ mod object_errors; use std::borrow::Cow; +#[allow(deprecated)] +pub use crate::error::EnumerateError; pub use crate::error::{ EnumError, ExclusiveMaximumError, ExclusiveMinimumError, MaxItemsError, MaxLengthError, MaxPropertiesError, MaximumError, MinItemsError, MinLengthError, MinPropertiesError, diff --git a/crates/serde_valid/src/validation/generic.rs b/crates/serde_valid/src/validation/generic.rs index 5bfcc88..164e5fa 100644 --- a/crates/serde_valid/src/validation/generic.rs +++ b/crates/serde_valid/src/validation/generic.rs @@ -1,2 +1,5 @@ mod r#enum; +mod enumerate; +#[allow(deprecated)] +pub use enumerate::ValidateEnumerate; pub use r#enum::ValidateEnum; diff --git a/crates/serde_valid/src/validation/generic/enumerate.rs b/crates/serde_valid/src/validation/generic/enumerate.rs new file mode 100644 index 0000000..b7ff288 --- /dev/null +++ b/crates/serde_valid/src/validation/generic/enumerate.rs @@ -0,0 +1,159 @@ +#![allow(deprecated)] + +use crate::validation::ValidateCompositedEnumerate; +use crate::EnumError; + +/// Enumerate validation. +/// +/// See +/// +/// Note: `#[validate(enumerate = ...)]` is deprecated; use `#[validate(r#enum = ...)]`. +#[deprecated( + since = "2.0.2", + note = "use `ValidateEnum` and `validate_enum` instead" +)] +pub trait ValidateEnumerate { + fn validate_enumerate(&self, enumerate: &[T]) -> Result<(), EnumError>; +} + +macro_rules! impl_validate_generic_enumerate_literal { + ($type:ty) => { + impl ValidateEnumerate<$type> for $type { + fn validate_enumerate(&self, enumerate: &[$type]) -> Result<(), EnumError> { + if enumerate.iter().any(|candidate| candidate == self) { + Ok(()) + } else { + Err(EnumError::new(enumerate)) + } + } + } + + impl ValidateCompositedEnumerate<&[$type]> for T + where + T: ValidateEnumerate<$type>, + { + fn validate_composited_enumerate( + &self, + limit: &[$type], + ) -> Result<(), crate::validation::Composited> { + self.validate_enumerate(limit) + .map_err(crate::validation::Composited::Single) + } + } + }; +} + +impl_validate_generic_enumerate_literal!(i8); +impl_validate_generic_enumerate_literal!(i16); +impl_validate_generic_enumerate_literal!(i32); +impl_validate_generic_enumerate_literal!(i64); +#[cfg(feature = "i128")] +impl_validate_generic_enumerate_literal!(i128); +impl_validate_generic_enumerate_literal!(isize); +impl_validate_generic_enumerate_literal!(u8); +impl_validate_generic_enumerate_literal!(u16); +impl_validate_generic_enumerate_literal!(u32); +impl_validate_generic_enumerate_literal!(u64); +#[cfg(feature = "i128")] +impl_validate_generic_enumerate_literal!(u128); +impl_validate_generic_enumerate_literal!(usize); +impl_validate_generic_enumerate_literal!(std::num::NonZeroI8); +impl_validate_generic_enumerate_literal!(std::num::NonZeroI16); +impl_validate_generic_enumerate_literal!(std::num::NonZeroI32); +impl_validate_generic_enumerate_literal!(std::num::NonZeroI64); +#[cfg(feature = "i128")] +impl_validate_generic_enumerate_literal!(std::num::NonZeroI128); +impl_validate_generic_enumerate_literal!(std::num::NonZeroIsize); +impl_validate_generic_enumerate_literal!(std::num::NonZeroU8); +impl_validate_generic_enumerate_literal!(std::num::NonZeroU16); +impl_validate_generic_enumerate_literal!(std::num::NonZeroU32); +impl_validate_generic_enumerate_literal!(std::num::NonZeroU64); +#[cfg(feature = "i128")] +impl_validate_generic_enumerate_literal!(std::num::NonZeroU128); +impl_validate_generic_enumerate_literal!(std::num::NonZeroUsize); +impl_validate_generic_enumerate_literal!(f32); +impl_validate_generic_enumerate_literal!(f64); +impl_validate_generic_enumerate_literal!(char); + +macro_rules! impl_validate_generic_enumerate_str { + ($type:ty) => { + impl ValidateEnumerate<&'static str> for $type { + fn validate_enumerate(&self, enumerate: &[&'static str]) -> Result<(), EnumError> { + if enumerate.iter().any(|candidate| candidate == self) { + Ok(()) + } else { + Err(EnumError::new(enumerate)) + } + } + } + }; +} + +impl_validate_generic_enumerate_str!(&str); +impl_validate_generic_enumerate_str!(String); +impl_validate_generic_enumerate_str!(std::borrow::Cow<'_, str>); +impl_validate_generic_enumerate_str!(&std::ffi::OsStr); +impl_validate_generic_enumerate_str!(std::ffi::OsString); + +macro_rules! impl_validate_generic_enumerate_path { + ($type:ty) => { + impl ValidateEnumerate<&'static str> for $type { + fn validate_enumerate(&self, enumerate: &[&'static str]) -> Result<(), EnumError> { + if enumerate + .iter() + .any(|candidate| &std::path::Path::new(candidate) == self) + { + Ok(()) + } else { + Err(EnumError::new(enumerate)) + } + } + } + }; +} + +impl_validate_generic_enumerate_path!(&std::path::Path); +impl_validate_generic_enumerate_path!(std::path::PathBuf); + +impl ValidateCompositedEnumerate<&[&'static str]> for T +where + T: ValidateEnumerate<&'static str>, +{ + fn validate_composited_enumerate( + &self, + limit: &[&'static str], + ) -> Result<(), crate::validation::Composited> { + self.validate_enumerate(limit) + .map_err(crate::validation::Composited::Single) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct MyType(String); + + impl ValidateEnumerate<&'static str> for MyType { + fn validate_enumerate(&self, enumerate: &[&'static str]) -> Result<(), EnumError> { + self.0.validate_enumerate(enumerate) + } + } + + #[test] + fn test_validate_integer_vec_type_is_true() { + assert!(ValidateEnumerate::validate_enumerate(&1, &[1, 2, 3]).is_ok()); + } + + #[test] + fn test_validate_integer_vec_type_is_false() { + assert!(ValidateEnumerate::validate_enumerate(&1, &[2, 3, 4]).is_err()); + } + + #[test] + fn test_validate_custom_type() { + assert!( + ValidateEnumerate::validate_enumerate(&MyType("a".to_string()), &["a", "b"]).is_ok() + ); + } +}