dcbor_pattern/pattern/meta/
repeat_pattern.rs1use dcbor::prelude::*;
2
3use crate::{
4 Quantifier,
5 pattern::{Matcher, Path, Pattern, vm::Instr},
6};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct RepeatPattern {
11 pattern: Box<Pattern>,
12 quantifier: Quantifier,
13}
14
15impl RepeatPattern {
16 pub fn repeat(pattern: Pattern, quantifier: Quantifier) -> Self {
19 RepeatPattern { pattern: Box::new(pattern), quantifier }
20 }
21
22 pub fn new(pattern: Pattern) -> Self {
25 RepeatPattern {
26 pattern: Box::new(pattern),
27 quantifier: Quantifier::default(),
28 }
29 }
30
31 pub fn pattern(&self) -> &Pattern {
33 &self.pattern
34 }
35
36 pub fn quantifier(&self) -> &Quantifier {
38 &self.quantifier
39 }
40}
41
42impl Matcher for RepeatPattern {
43 fn paths(&self, haystack: &CBOR) -> Vec<Path> {
44 let inner_paths = self.pattern.paths(haystack);
49 let matches = !inner_paths.is_empty();
50
51 if matches {
52 if self.quantifier.contains(1) {
54 inner_paths
55 } else {
56 vec![]
57 }
58 } else {
59 if self.quantifier.contains(0) {
61 vec![vec![haystack.clone()]]
63 } else {
64 vec![]
66 }
67 }
68 }
69
70 fn paths_with_captures(
71 &self,
72 haystack: &CBOR,
73 ) -> (Vec<Path>, std::collections::HashMap<String, Vec<Path>>) {
74 (self.paths(haystack), std::collections::HashMap::new())
77 }
78
79 fn compile(
80 &self,
81 code: &mut Vec<Instr>,
82 literals: &mut Vec<Pattern>,
83 _captures: &mut Vec<String>,
84 ) {
85 let idx = literals.len();
87 literals.push((*self.pattern).clone());
88 code.push(Instr::Repeat { pat_idx: idx, quantifier: self.quantifier });
89 }
90
91 fn collect_capture_names(&self, names: &mut Vec<String>) {
92 self.pattern.collect_capture_names(names);
94 }
95}
96
97impl std::fmt::Display for RepeatPattern {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 let formatted_range = self.quantifier.to_string();
100 write!(f, "({}){}", self.pattern, formatted_range)
101 }
102}