1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
use crate::traits::IsUnique;
/// Uniqueness validation of the array items.
///
/// See <https://json-schema.org/understanding-json-schema/reference/array.html#unique_items>
///
/// ```rust
/// use serde_json::json;
/// use serde_valid::{Validate, ValidateUniqueItems};
///
/// struct MyType(Vec<i32>);
///
/// impl ValidateUniqueItems for MyType {
/// fn validate_unique_items(&self) -> Result<(), serde_valid::UniqueItemsError> {
/// self.0.validate_unique_items()
/// }
/// }
///
/// #[derive(Validate)]
/// struct TestStruct {
/// #[validate(unique_items)]
/// val: MyType,
/// }
///
/// let s = TestStruct {
/// val: MyType(vec![1, 2, 1]),
/// };
///
/// assert_eq!(
/// s.validate().unwrap_err().to_string(),
/// json!({
/// "errors": [],
/// "properties": {
/// "val": {
/// "errors": ["The items must be unique."]
/// }
/// }
/// })
/// .to_string()
/// );
/// ```
pub trait ValidateUniqueItems {
fn validate_unique_items(&self) -> Result<(), crate::UniqueItemsError>;
}
impl<T> ValidateUniqueItems for Vec<T>
where
T: std::cmp::Eq + std::hash::Hash + std::fmt::Debug,
{
fn validate_unique_items(&self) -> Result<(), crate::UniqueItemsError> {
if self.is_unique() {
Ok(())
} else {
Err(crate::UniqueItemsError {})
}
}
}
impl<T, const N: usize> ValidateUniqueItems for [T; N]
where
T: std::cmp::Eq + std::hash::Hash + std::fmt::Debug,
{
fn validate_unique_items(&self) -> Result<(), crate::UniqueItemsError> {
if self.is_unique() {
Ok(())
} else {
Err(crate::UniqueItemsError {})
}
}
}
impl<T> ValidateUniqueItems for Option<T>
where
T: ValidateUniqueItems,
{
fn validate_unique_items(&self) -> Result<(), crate::UniqueItemsError> {
match self {
Some(value) => value.validate_unique_items(),
None => Ok(()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_array_unique_items_array_type_is_true() {
assert!(ValidateUniqueItems::validate_unique_items(&[1, 2, 3, 4]).is_ok());
}
#[test]
fn test_validate_array_unique_items_vec_type_is_true() {
assert!(ValidateUniqueItems::validate_unique_items(&vec![1, 2, 3, 4]).is_ok());
}
#[test]
fn test_validate_array_unique_items_is_false() {
assert!(ValidateUniqueItems::validate_unique_items(&[1, 2, 3, 3]).is_err());
}
}