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
103 || self.patterns().iter().any(|p| p.is_complex())
104 }
105
106 fn paths_with_captures(
107 &self,
108 cbor: &CBOR,
109 ) -> (Vec<Path>, std::collections::HashMap<String, Vec<Path>>) {
110 (self.paths(cbor), std::collections::HashMap::new())
114 }
115}
116
117impl std::fmt::Display for SequencePattern {
118 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119 if self.patterns().is_empty() {
120 write!(f, "()")
121 } else {
122 let patterns_str: Vec<String> =
123 self.patterns().iter().map(|p| p.to_string()).collect();
124 write!(f, "{}", patterns_str.join(", "))
125 }
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use dcbor_parse::parse_dcbor_item;
132
133 use super::*;
134
135 #[test]
136 fn test_sequence_pattern_new() {
137 let patterns = vec![Pattern::text("first"), Pattern::text("second")];
138 let sequence = SequencePattern::new(patterns.clone());
139 assert_eq!(sequence.patterns(), &patterns);
140 }
141
142 #[test]
143 fn test_sequence_pattern_empty() {
144 let sequence = SequencePattern::new(vec![]);
145 assert!(sequence.is_empty());
146 assert_eq!(sequence.len(), 0);
147 }
148
149 #[test]
150 fn test_sequence_pattern_len() {
151 let patterns =
152 vec![Pattern::text("a"), Pattern::text("b"), Pattern::text("c")];
153 let sequence = SequencePattern::new(patterns);
154 assert!(!sequence.is_empty());
155 assert_eq!(sequence.len(), 3);
156 }
157
158 #[test]
159 fn test_sequence_pattern_display() {
160 let patterns = vec![
161 Pattern::text("first"),
162 Pattern::text("second"),
163 Pattern::text("third"),
164 ];
165 let sequence = SequencePattern::new(patterns);
166 let display = sequence.to_string();
167 assert!(display.contains("first"));
168 assert!(display.contains("second"));
169 assert!(display.contains("third"));
170 assert!(display.contains(", "));
171 }
172
173 #[test]
174 fn test_sequence_pattern_display_empty() {
175 let sequence = SequencePattern::new(vec![]);
176 assert_eq!(sequence.to_string(), "()");
177 }
178
179 #[test]
180 fn test_sequence_pattern_is_complex() {
181 let empty_sequence = SequencePattern::new(vec![]);
183 assert!(!empty_sequence.is_complex());
184
185 let single_sequence = SequencePattern::new(vec![Pattern::text("test")]);
187 assert!(!single_sequence.is_complex());
188
189 let multi_sequence = SequencePattern::new(vec![
191 Pattern::text("first"),
192 Pattern::text("second"),
193 ]);
194 assert!(multi_sequence.is_complex());
195 }
196
197 #[test]
198 fn test_sequence_pattern_compile() {
199 let patterns = vec![Pattern::text("first"), Pattern::text("second")];
200 let sequence = SequencePattern::new(patterns);
201
202 let mut code = Vec::new();
203 let mut literals = Vec::new();
204 let mut captures = Vec::new();
205
206 sequence.compile(&mut code, &mut literals, &mut captures);
207
208 assert!(!code.is_empty());
210 assert_eq!(literals.len(), 2);
212 }
213
214 #[test]
215 fn test_sequence_pattern_compile_empty() {
216 let sequence = SequencePattern::new(vec![]);
217
218 let mut code = Vec::new();
219 let mut literals = Vec::new();
220 let mut captures = Vec::new();
221
222 sequence.compile(&mut code, &mut literals, &mut captures);
223
224 assert!(code.is_empty());
226 }
227
228 #[test]
229 fn test_sequence_pattern_collect_capture_names() {
230 let patterns = vec![
231 Pattern::capture("first", Pattern::text("a")),
232 Pattern::text("b"),
233 Pattern::capture("third", Pattern::text("c")),
234 ];
235 let sequence = SequencePattern::new(patterns);
236
237 let mut names = Vec::new();
238 sequence.collect_capture_names(&mut names);
239
240 assert_eq!(names.len(), 2);
241 assert!(names.contains(&"first".to_string()));
242 assert!(names.contains(&"third".to_string()));
243 }
244
245 #[test]
246 fn test_sequence_pattern_paths() {
247 let patterns = vec![Pattern::text("a"), Pattern::text("b")];
248 let sequence = SequencePattern::new(patterns);
249
250 let cbor = "test".to_cbor();
251 let paths = sequence.paths(&cbor);
252
253 assert!(paths.is_empty());
255 }
256
257 #[test]
258 fn test_sequence_pattern_with_array() {
259 let _array_cbor =
261 parse_dcbor_item(r#"["first", "second", "third"]"#).unwrap();
262
263 let sequence = SequencePattern::new(vec![
265 Pattern::text("first"),
266 Pattern::text("second"),
267 Pattern::text("third"),
268 ]);
269
270 assert_eq!(sequence.len(), 3);
272 assert!(!sequence.is_empty());
273 assert!(sequence.is_complex()); let display = sequence.to_string();
277 assert!(display.contains("first"));
278 assert!(display.contains("second"));
279 assert!(display.contains("third"));
280 assert!(display.contains(", "));
281 }
282
283 #[test]
284 fn test_sequence_pattern_with_mixed_types() {
285 let _mixed_array =
287 parse_dcbor_item(r#"[42, "hello", true, null]"#).unwrap();
288
289 let sequence = SequencePattern::new(vec![
290 Pattern::number(42),
291 Pattern::text("hello"),
292 Pattern::bool(true),
293 Pattern::null(),
294 ]);
295
296 assert_eq!(sequence.len(), 4);
298 assert!(sequence.is_complex());
299
300 let mut code = Vec::new();
302 let mut literals = Vec::new();
303 let mut captures = Vec::new();
304 sequence.compile(&mut code, &mut literals, &mut captures);
305
306 assert!(!code.is_empty());
307 assert_eq!(literals.len(), 4); }
309
310 #[test]
311 fn test_sequence_pattern_partial_match() {
312 let _large_array =
314 parse_dcbor_item(r#"["start", "middle1", "middle2", "end"]"#)
315 .unwrap();
316
317 let sequence = SequencePattern::new(vec![
319 Pattern::text("middle1"),
320 Pattern::text("middle2"),
321 ]);
322
323 assert_eq!(sequence.len(), 2);
325 assert!(!sequence.is_empty());
326 assert!(sequence.is_complex());
327
328 let display = sequence.to_string();
329 assert!(display.contains("middle1"));
330 assert!(display.contains("middle2"));
331 assert!(display.contains(", "));
332 }
333
334 #[test]
335 fn test_sequence_pattern_with_captures() {
336 let sequence = SequencePattern::new(vec![
338 Pattern::capture("first_value", Pattern::text("hello")),
339 Pattern::capture("second_value", Pattern::number(42)),
340 Pattern::text("world"),
341 ]);
342
343 let mut names = Vec::new();
344 sequence.collect_capture_names(&mut names);
345
346 assert_eq!(names.len(), 2);
347 assert!(names.contains(&"first_value".to_string()));
348 assert!(names.contains(&"second_value".to_string()));
349
350 let display = sequence.to_string();
352 assert!(display.contains("@first_value"));
353 assert!(display.contains("@second_value"));
354 assert!(display.contains(", "));
355 }
356
357 #[test]
358 fn test_sequence_pattern_with_simple_types() {
359 let _simple_array = parse_dcbor_item(r#"["text", 123, true]"#).unwrap();
361
362 let sequence = SequencePattern::new(vec![
363 Pattern::text("text"),
364 Pattern::number(123),
365 Pattern::bool(true),
366 ]);
367
368 assert_eq!(sequence.len(), 3);
370 assert!(sequence.is_complex());
371
372 let mut code = Vec::new();
374 let mut literals = Vec::new();
375 let mut captures = Vec::new();
376 sequence.compile(&mut code, &mut literals, &mut captures);
377
378 assert!(!code.is_empty());
379 assert_eq!(literals.len(), 3); }
381
382 #[test]
383 fn test_sequence_pattern_with_byte_strings() {
384 let _bytes_array =
386 parse_dcbor_item(r#"[h'deadbeef', h'cafebabe', "text"]"#).unwrap();
387
388 let sequence = SequencePattern::new(vec![
389 Pattern::byte_string(hex::decode("deadbeef").unwrap()),
390 Pattern::byte_string(hex::decode("cafebabe").unwrap()),
391 Pattern::text("text"),
392 ]);
393
394 assert_eq!(sequence.len(), 3);
396 assert!(sequence.is_complex());
397
398 let patterns = sequence.patterns();
400 assert_eq!(patterns.len(), 3);
401
402 let display = sequence.to_string();
404 assert!(display.contains(", "));
405 }
406}