validify/
traits.rs

1use indexmap::{IndexMap, IndexSet};
2use std::borrow::Cow;
3use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
4use std::hash::Hash;
5
6/// Used by the [validate_length][crate::validation::length::validate_length]
7/// function to validate the size of `T`.
8///
9/// The trait is implemented for common container types and can be implemented
10/// on anything that needs to be validated by `length`.
11///
12/// Note: string implementations count the characters, not the bytes.
13pub trait Length {
14    fn length(&self) -> usize;
15}
16
17impl<T> Length for &T
18where
19    T: Length,
20{
21    fn length(&self) -> usize {
22        <T as Length>::length(*self)
23    }
24}
25
26impl Length for String {
27    fn length(&self) -> usize {
28        self.chars().count()
29    }
30}
31
32impl Length for &str {
33    fn length(&self) -> usize {
34        self.chars().count()
35    }
36}
37
38impl Length for Cow<'_, str> {
39    fn length(&self) -> usize {
40        self.chars().count()
41    }
42}
43
44impl<T> Length for Vec<T> {
45    fn length(&self) -> usize {
46        self.len()
47    }
48}
49
50impl<T> Length for &[T] {
51    fn length(&self) -> usize {
52        self.len()
53    }
54}
55
56impl<T, const N: usize> Length for [T; N] {
57    fn length(&self) -> usize {
58        N
59    }
60}
61
62impl<K, V, S> Length for HashMap<K, V, S> {
63    fn length(&self) -> usize {
64        self.len()
65    }
66}
67
68impl<T, S> Length for HashSet<T, S> {
69    fn length(&self) -> usize {
70        self.len()
71    }
72}
73
74impl<K, V> Length for BTreeMap<K, V> {
75    fn length(&self) -> usize {
76        self.len()
77    }
78}
79
80impl<T> Length for BTreeSet<T> {
81    fn length(&self) -> usize {
82        self.len()
83    }
84}
85
86impl<K, V> Length for IndexMap<K, V> {
87    fn length(&self) -> usize {
88        self.len()
89    }
90}
91
92impl<T> Length for IndexSet<T> {
93    fn length(&self) -> usize {
94        self.len()
95    }
96}
97
98/// Used by the [validate_contains][crate::validation::contains::validate_contains] function.
99///
100/// In `contains`, the field is checked if it contains the provided value.
101///
102/// In `in/not_in`, the given value is checked if it contains the field.
103pub trait Contains<T> {
104    fn has_element(&self, needle: &T) -> bool;
105}
106
107impl<T, C> Contains<C> for &T
108where
109    T: Contains<C>,
110{
111    fn has_element(&self, needle: &C) -> bool {
112        <T as Contains<C>>::has_element(self, needle)
113    }
114}
115
116impl<T> Contains<T> for Vec<T>
117where
118    T: PartialEq,
119{
120    fn has_element(&self, needle: &T) -> bool {
121        self.contains(needle)
122    }
123}
124
125impl<T> Contains<&T> for Vec<T>
126where
127    T: PartialEq,
128{
129    fn has_element(&self, needle: &&T) -> bool {
130        self.contains(*needle)
131    }
132}
133
134impl Contains<&str> for Vec<String> {
135    fn has_element(&self, needle: &&str) -> bool {
136        self.contains(&needle.to_string())
137    }
138}
139
140impl<T> Contains<T> for &[T]
141where
142    T: PartialEq,
143{
144    fn has_element(&self, needle: &T) -> bool {
145        self.contains(needle)
146    }
147}
148
149impl<T, const N: usize> Contains<T> for [T; N]
150where
151    T: PartialEq,
152{
153    fn has_element(&self, needle: &T) -> bool {
154        self.contains(needle)
155    }
156}
157
158impl<K, V> Contains<K> for HashMap<K, V>
159where
160    K: PartialEq + Eq + Hash,
161{
162    fn has_element(&self, needle: &K) -> bool {
163        self.contains_key(needle)
164    }
165}
166
167impl<V> Contains<&str> for HashMap<String, V> {
168    fn has_element(&self, needle: &&str) -> bool {
169        self.contains_key(&needle.to_string())
170    }
171}
172
173impl<K, V> Contains<&K> for HashMap<K, V>
174where
175    K: PartialEq + Eq + Hash,
176{
177    fn has_element(&self, needle: &&K) -> bool {
178        self.contains_key(*needle)
179    }
180}
181
182impl Contains<&str> for String {
183    fn has_element(&self, needle: &&str) -> bool {
184        self.contains(needle)
185    }
186}
187
188impl Contains<String> for String {
189    fn has_element(&self, needle: &String) -> bool {
190        self.contains(needle)
191    }
192}
193
194impl Contains<String> for &str {
195    fn has_element(&self, needle: &String) -> bool {
196        self.contains(needle)
197    }
198}
199
200impl Contains<&str> for &str {
201    fn has_element(&self, needle: &&str) -> bool {
202        self.contains(needle)
203    }
204}
205
206impl Contains<&String> for &[&str] {
207    fn has_element(&self, needle: &&String) -> bool {
208        self.contains(&needle.as_str())
209    }
210}
211
212impl<const N: usize> Contains<&String> for [&str; N] {
213    fn has_element(&self, needle: &&String) -> bool {
214        self.contains(&needle.as_str())
215    }
216}
217
218impl Contains<&str> for Cow<'_, str> {
219    fn has_element(&self, needle: &&str) -> bool {
220        self.contains(needle)
221    }
222}