compact_str/features/
garde.rs1use crate::CompactString;
2
3#[cfg_attr(docsrs, doc(cfg(feature = "garde")))]
4impl garde::rules::AsStr for CompactString {
5 fn as_str(&self) -> &str {
6 self.as_str()
7 }
8}
9
10#[cfg_attr(docsrs, doc(cfg(feature = "garde")))]
11impl garde::rules::length::HasBytes for CompactString {
12 fn num_bytes(&self) -> usize {
13 self.len()
14 }
15}
16
17#[cfg_attr(docsrs, doc(cfg(feature = "garde")))]
18impl garde::rules::length::HasChars for CompactString {
19 fn num_chars(&self) -> usize {
20 self.chars().count()
21 }
22}
23
24#[cfg_attr(docsrs, doc(cfg(feature = "garde")))]
25impl garde::rules::length::HasSimpleLength for CompactString {
26 fn length(&self) -> usize {
27 self.len()
28 }
29}
30
31#[cfg_attr(docsrs, doc(cfg(feature = "garde")))]
32impl garde::rules::length::HasUtf16CodeUnits for CompactString {
33 fn num_code_units(&self) -> usize {
34 self.encode_utf16().count()
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use garde::Validate;
41
42 use crate::CompactString;
43
44 #[derive(garde::Validate)]
47 struct AsciiTest {
48 #[garde(ascii)]
49 value: CompactString,
50 }
51
52 #[test]
53 fn as_str_ascii_valid() {
54 let t = AsciiTest {
55 value: CompactString::from("hello world!"),
56 };
57 assert!(t.validate().is_ok());
58 }
59
60 #[test]
61 fn as_str_ascii_invalid() {
62 let t = AsciiTest {
63 value: CompactString::from("héllo"),
64 };
65 assert!(t.validate().is_err());
66 }
67
68 #[derive(garde::Validate)]
71 struct ByteLengthTest {
72 #[garde(length(bytes, min = 1, max = 4))]
73 value: CompactString,
74 }
75
76 #[test]
77 fn has_bytes_within_limit() {
78 let t = ByteLengthTest {
80 value: CompactString::from("hi"),
81 };
82 assert!(t.validate().is_ok());
83 }
84
85 #[test]
86 fn has_bytes_exceeds_limit() {
87 let t = ByteLengthTest {
89 value: CompactString::from("héllo"),
90 };
91 assert!(t.validate().is_err());
92 }
93
94 #[test]
95 fn has_bytes_empty_fails() {
96 let t = ByteLengthTest {
97 value: CompactString::new(""),
98 };
99 assert!(t.validate().is_err());
100 }
101
102 #[derive(garde::Validate)]
105 struct CharLengthTest {
106 #[garde(length(chars, min = 1, max = 3))]
107 value: CompactString,
108 }
109
110 #[test]
111 fn has_chars_within_limit() {
112 let t = CharLengthTest {
114 value: CompactString::from("héy"),
115 };
116 assert!(t.validate().is_ok());
117 }
118
119 #[test]
120 fn has_chars_exceeds_limit() {
121 let t = CharLengthTest {
122 value: CompactString::from("abcd"),
123 };
124 assert!(t.validate().is_err());
125 }
126
127 #[test]
128 fn has_chars_empty_fails() {
129 let t = CharLengthTest {
130 value: CompactString::new(""),
131 };
132 assert!(t.validate().is_err());
133 }
134
135 #[derive(garde::Validate)]
137 struct SimpleLengthTest {
138 #[garde(length(min = 2, max = 5))]
139 value: CompactString,
140 }
141
142 #[test]
143 fn has_simple_length_valid() {
144 let t = SimpleLengthTest {
145 value: CompactString::from("abc"),
146 };
147 assert!(t.validate().is_ok());
148 }
149
150 #[test]
151 fn has_simple_length_too_short() {
152 let t = SimpleLengthTest {
153 value: CompactString::from("a"),
154 };
155 assert!(t.validate().is_err());
156 }
157
158 #[test]
159 fn has_simple_length_too_long() {
160 let t = SimpleLengthTest {
161 value: CompactString::from("abcdef"),
162 };
163 assert!(t.validate().is_err());
164 }
165
166 #[derive(garde::Validate)]
169 struct Utf16LengthTest {
170 #[garde(length(utf16, min = 1, max = 2))]
171 value: CompactString,
172 }
173
174 #[test]
175 fn has_utf16_bmp_char_valid() {
176 let t = Utf16LengthTest {
178 value: CompactString::from("é"),
179 };
180 assert!(t.validate().is_ok());
181 }
182
183 #[test]
184 fn has_utf16_surrogate_pair_valid() {
185 let t = Utf16LengthTest {
187 value: CompactString::from("😀"),
188 };
189 assert!(t.validate().is_ok());
190 }
191
192 #[test]
193 fn has_utf16_exceeds_limit() {
194 let t = Utf16LengthTest {
196 value: CompactString::from("😀😀"),
197 };
198 assert!(t.validate().is_err());
199 }
200
201 #[derive(garde::Validate)]
203 struct StringTest {
204 #[garde(ascii)]
205 #[garde(length(bytes, min = 1, max = 100))]
206 #[garde(length(chars, min = 1, max = 100))]
207 #[garde(length(min = 1, max = 100))]
208 #[garde(length(utf16, min = 1, max = 100))]
209 value: std::string::String,
210 }
211
212 #[derive(garde::Validate)]
213 struct CompactTest {
214 #[garde(ascii)]
215 #[garde(length(bytes, min = 1, max = 100))]
216 #[garde(length(chars, min = 1, max = 100))]
217 #[garde(length(min = 1, max = 100))]
218 #[garde(length(utf16, min = 1, max = 100))]
219 value: CompactString,
220 }
221
222 #[test]
223 fn matches_string_behavior() {
224 for s in &["hello", "héllo", "😀", "a", ""] {
225 let string_result = StringTest {
226 value: std::string::String::from(*s),
227 }
228 .validate();
229 let compact_result = CompactTest {
230 value: CompactString::from(*s),
231 }
232 .validate();
233 assert_eq!(
234 string_result.is_ok(),
235 compact_result.is_ok(),
236 "mismatch for input {:?}",
237 s
238 );
239 }
240 }
241}