karbon_framework/validation/constraints/collection/
unique.rs1use crate::validation::constraints::{ConstraintResult, ConstraintViolation};
2use std::collections::HashSet;
3use std::hash::Hash;
4
5pub struct Unique {
9 pub message: String,
10}
11
12impl Default for Unique {
13 fn default() -> Self {
14 Self {
15 message: "This collection should contain only unique elements.".to_string(),
16 }
17 }
18}
19
20impl Unique {
21 pub fn new() -> Self {
22 Self::default()
23 }
24
25 pub fn with_message(mut self, message: impl Into<String>) -> Self {
26 self.message = message.into();
27 self
28 }
29
30 pub fn validate_slice<T: Eq + Hash>(&self, value: &[T]) -> ConstraintResult {
31 let mut seen = HashSet::new();
32 for item in value {
33 if !seen.insert(item) {
34 return Err(ConstraintViolation::new(
35 "Unique",
36 &self.message,
37 format!("count: {}", value.len()),
38 ));
39 }
40 }
41 Ok(())
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_unique_elements() {
51 let constraint = Unique::new();
52 assert!(constraint.validate_slice(&[1, 2, 3, 4]).is_ok());
53 assert!(constraint.validate_slice(&["a", "b", "c"]).is_ok());
54 assert!(constraint.validate_slice::<i32>(&[]).is_ok());
55 }
56
57 #[test]
58 fn test_duplicate_elements() {
59 let constraint = Unique::new();
60 assert!(constraint.validate_slice(&[1, 2, 3, 2]).is_err());
61 assert!(constraint.validate_slice(&["a", "b", "a"]).is_err());
62 assert!(constraint.validate_slice(&[1, 1]).is_err());
63 }
64
65 #[test]
66 fn test_single_element() {
67 let constraint = Unique::new();
68 assert!(constraint.validate_slice(&[42]).is_ok());
69 }
70}