dcbor_pattern/pattern/meta/
sequence_pattern.rs1use dcbor::prelude::*;
2
3use crate::pattern::{Matcher, Path, Pattern, vm::Instr};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct SequencePattern(Vec<Pattern>);
25
26impl SequencePattern {
27 pub fn new(patterns: Vec<Pattern>) -> Self { Self(patterns) }
29
30 pub fn patterns(&self) -> &[Pattern] { &self.0 }
32
33 pub fn is_empty(&self) -> bool { self.patterns().is_empty() }
35
36 pub fn len(&self) -> usize { self.patterns().len() }
38}
39
40impl Matcher for SequencePattern {
41 fn paths(&self, _haystack: &CBOR) -> Vec<Path> {
42 vec![]
53 }
54
55 fn compile(
56 &self,
57 code: &mut Vec<Instr>,
58 literals: &mut Vec<Pattern>,
59 captures: &mut Vec<String>,
60 ) {
61 if self.patterns().is_empty() {
62 return;
64 }
65
66 if self.patterns().len() == 1 {
67 self.patterns()[0].compile(code, literals, captures);
69 return;
70 }
71
72 for (i, pattern) in self.patterns().iter().enumerate() {
76 if i > 0 {
77 code.push(Instr::ExtendSequence);
80 }
81
82 pattern.compile(code, literals, captures);
84
85 if i > 0 {
86 code.push(Instr::CombineSequence);
89 }
90 }
91 }
92
93 fn collect_capture_names(&self, names: &mut Vec<String>) {
94 for pattern in self.patterns() {
95 pattern.collect_capture_names(names);
96 }
97 }
98
99 fn is_complex(&self) -> bool {
100 self.patterns().len() > 1 || self.patterns().iter().any(|p| p.is_complex())
103 }
104
105 fn paths_with_captures(
106 &self,
107 cbor: &CBOR,
108 ) -> (Vec<Path>, std::collections::HashMap<String, Vec<Path>>) {
109 (self.paths(cbor), std::collections::HashMap::new())
113 }
114}
115
116impl std::fmt::Display for SequencePattern {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 if self.patterns().is_empty() {
119 write!(f, "()")
120 } else {
121 let patterns_str: Vec<String> =
122 self.patterns().iter().map(|p| p.to_string()).collect();
123 write!(f, "{}", patterns_str.join(", "))
124 }
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use dcbor_parse::parse_dcbor_item;
131
132 use super::*;
133
134 #[test]
135 fn test_sequence_pattern_new() {
136 let patterns = vec![Pattern::text("first"), Pattern::text("second")];
137 let sequence = SequencePattern::new(patterns.clone());
138 assert_eq!(sequence.patterns(), &patterns);
139 }
140
141 #[test]
142 fn test_sequence_pattern_empty() {
143 let sequence = SequencePattern::new(vec![]);
144 assert!(sequence.is_empty());
145 assert_eq!(sequence.len(), 0);
146 }
147
148 #[test]
149 fn test_sequence_pattern_len() {
150 let patterns =
151 vec![Pattern::text("a"), Pattern::text("b"), Pattern::text("c")];
152 let sequence = SequencePattern::new(patterns);
153 assert!(!sequence.is_empty());
154 assert_eq!(sequence.len(), 3);
155 }
156
157 #[test]
158 fn test_sequence_pattern_display() {
159 let patterns = vec![
160 Pattern::text("first"),
161 Pattern::text("second"),
162 Pattern::text("third"),
163 ];
164 let sequence = SequencePattern::new(patterns);
165 let display = sequence.to_string();
166 assert!(display.contains("first"));
167 assert!(display.contains("second"));
168 assert!(display.contains("third"));
169 assert!(display.contains(", "));
170 }
171
172 #[test]
173 fn test_sequence_pattern_display_empty() {
174 let sequence = SequencePattern::new(vec![]);
175 assert_eq!(sequence.to_string(), "()");
176 }
177
178 #[test]
179 fn test_sequence_pattern_is_complex() {
180 let empty_sequence = SequencePattern::new(vec![]);
182 assert!(!empty_sequence.is_complex());
183
184 let single_sequence = SequencePattern::new(vec![Pattern::text("test")]);
186 assert!(!single_sequence.is_complex());
187
188 let multi_sequence = SequencePattern::new(vec![
190 Pattern::text("first"),
191 Pattern::text("second"),
192 ]);
193 assert!(multi_sequence.is_complex());
194 }
195
196 #[test]
197 fn test_sequence_pattern_compile() {
198 let patterns = vec![Pattern::text("first"), Pattern::text("second")];
199 let sequence = SequencePattern::new(patterns);
200
201 let mut code = Vec::new();
202 let mut literals = Vec::new();
203 let mut captures = Vec::new();
204
205 sequence.compile(&mut code, &mut literals, &mut captures);
206
207 assert!(!code.is_empty());
209 assert_eq!(literals.len(), 2);
211 }
212
213 #[test]
214 fn test_sequence_pattern_compile_empty() {
215 let sequence = SequencePattern::new(vec![]);
216
217 let mut code = Vec::new();
218 let mut literals = Vec::new();
219 let mut captures = Vec::new();
220
221 sequence.compile(&mut code, &mut literals, &mut captures);
222
223 assert!(code.is_empty());
225 }
226
227 #[test]
228 fn test_sequence_pattern_collect_capture_names() {
229 let patterns = vec![
230 Pattern::capture("first", Pattern::text("a")),
231 Pattern::text("b"),
232 Pattern::capture("third", Pattern::text("c")),
233 ];
234 let sequence = SequencePattern::new(patterns);
235
236 let mut names = Vec::new();
237 sequence.collect_capture_names(&mut names);
238
239 assert_eq!(names.len(), 2);
240 assert!(names.contains(&"first".to_string()));
241 assert!(names.contains(&"third".to_string()));
242 }
243
244 #[test]
245 fn test_sequence_pattern_paths() {
246 let patterns = vec![Pattern::text("a"), Pattern::text("b")];
247 let sequence = SequencePattern::new(patterns);
248
249 let cbor = "test".to_cbor();
250 let paths = sequence.paths(&cbor);
251
252 assert!(paths.is_empty());
254 }
255
256 #[test]
257 fn test_sequence_pattern_with_array() {
258 let _array_cbor =
260 parse_dcbor_item(r#"["first", "second", "third"]"#).unwrap();
261
262 let sequence = SequencePattern::new(vec![
264 Pattern::text("first"),
265 Pattern::text("second"),
266 Pattern::text("third"),
267 ]);
268
269 assert_eq!(sequence.len(), 3);
271 assert!(!sequence.is_empty());
272 assert!(sequence.is_complex()); let display = sequence.to_string();
276 assert!(display.contains("first"));
277 assert!(display.contains("second"));
278 assert!(display.contains("third"));
279 assert!(display.contains(", "));
280 }
281
282 #[test]
283 fn test_sequence_pattern_with_mixed_types() {
284 let _mixed_array =
286 parse_dcbor_item(r#"[42, "hello", true, null]"#).unwrap();
287
288 let sequence = SequencePattern::new(vec![
289 Pattern::number(42),
290 Pattern::text("hello"),
291 Pattern::bool(true),
292 Pattern::null(),
293 ]);
294
295 assert_eq!(sequence.len(), 4);
297 assert!(sequence.is_complex());
298
299 let mut code = Vec::new();
301 let mut literals = Vec::new();
302 let mut captures = Vec::new();
303 sequence.compile(&mut code, &mut literals, &mut captures);
304
305 assert!(!code.is_empty());
306 assert_eq!(literals.len(), 4); }
308
309 #[test]
310 fn test_sequence_pattern_partial_match() {
311 let _large_array =
313 parse_dcbor_item(r#"["start", "middle1", "middle2", "end"]"#)
314 .unwrap();
315
316 let sequence = SequencePattern::new(vec![
318 Pattern::text("middle1"),
319 Pattern::text("middle2"),
320 ]);
321
322 assert_eq!(sequence.len(), 2);
324 assert!(!sequence.is_empty());
325 assert!(sequence.is_complex());
326
327 let display = sequence.to_string();
328 assert!(display.contains("middle1"));
329 assert!(display.contains("middle2"));
330 assert!(display.contains(", "));
331 }
332
333 #[test]
334 fn test_sequence_pattern_with_captures() {
335 let sequence = SequencePattern::new(vec![
337 Pattern::capture("first_value", Pattern::text("hello")),
338 Pattern::capture("second_value", Pattern::number(42)),
339 Pattern::text("world"),
340 ]);
341
342 let mut names = Vec::new();
343 sequence.collect_capture_names(&mut names);
344
345 assert_eq!(names.len(), 2);
346 assert!(names.contains(&"first_value".to_string()));
347 assert!(names.contains(&"second_value".to_string()));
348
349 let display = sequence.to_string();
351 assert!(display.contains("@first_value"));
352 assert!(display.contains("@second_value"));
353 assert!(display.contains(", "));
354 }
355
356 #[test]
357 fn test_sequence_pattern_with_simple_types() {
358 let _simple_array = parse_dcbor_item(r#"["text", 123, true]"#).unwrap();
360
361 let sequence = SequencePattern::new(vec![
362 Pattern::text("text"),
363 Pattern::number(123),
364 Pattern::bool(true),
365 ]);
366
367 assert_eq!(sequence.len(), 3);
369 assert!(sequence.is_complex());
370
371 let mut code = Vec::new();
373 let mut literals = Vec::new();
374 let mut captures = Vec::new();
375 sequence.compile(&mut code, &mut literals, &mut captures);
376
377 assert!(!code.is_empty());
378 assert_eq!(literals.len(), 3); }
380
381 #[test]
382 fn test_sequence_pattern_with_byte_strings() {
383 let _bytes_array =
385 parse_dcbor_item(r#"[h'deadbeef', h'cafebabe', "text"]"#).unwrap();
386
387 let sequence = SequencePattern::new(vec![
388 Pattern::byte_string(hex::decode("deadbeef").unwrap()),
389 Pattern::byte_string(hex::decode("cafebabe").unwrap()),
390 Pattern::text("text"),
391 ]);
392
393 assert_eq!(sequence.len(), 3);
395 assert!(sequence.is_complex());
396
397 let patterns = sequence.patterns();
399 assert_eq!(patterns.len(), 3);
400
401 let display = sequence.to_string();
403 assert!(display.contains(", "));
404 }
405}