dcbor_pattern/pattern/meta/
meta_pattern.rs

1use dcbor::prelude::*;
2
3use super::{
4    AndPattern, AnyPattern, CapturePattern, NotPattern, OrPattern,
5    RepeatPattern, SearchPattern, SequencePattern,
6};
7use crate::pattern::{Matcher, Path, Pattern, vm::Instr};
8
9/// Pattern for combining and modifying other patterns.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum MetaPattern {
12    /// Always matches.
13    Any(AnyPattern),
14    /// Matches if all contained patterns match.
15    And(AndPattern),
16    /// Matches if any contained pattern matches.
17    Or(OrPattern),
18    /// Matches if the inner pattern does not match.
19    Not(NotPattern),
20    /// Matches with repetition.
21    Repeat(RepeatPattern),
22    /// Captures a pattern match.
23    Capture(CapturePattern),
24    /// Searches the entire dCBOR tree for matches.
25    Search(SearchPattern),
26    /// Matches a sequence of patterns in order.
27    Sequence(SequencePattern),
28}
29
30impl Matcher for MetaPattern {
31    fn paths(&self, haystack: &CBOR) -> Vec<Path> {
32        match self {
33            MetaPattern::Any(pattern) => pattern.paths(haystack),
34            MetaPattern::And(pattern) => pattern.paths(haystack),
35            MetaPattern::Or(pattern) => pattern.paths(haystack),
36            MetaPattern::Not(pattern) => pattern.paths(haystack),
37            MetaPattern::Repeat(pattern) => pattern.paths(haystack),
38            MetaPattern::Capture(pattern) => pattern.paths(haystack),
39            MetaPattern::Search(pattern) => pattern.paths(haystack),
40            MetaPattern::Sequence(pattern) => pattern.paths(haystack),
41        }
42    }
43
44    fn compile(
45        &self,
46        code: &mut Vec<Instr>,
47        lits: &mut Vec<Pattern>,
48        captures: &mut Vec<String>,
49    ) {
50        match self {
51            MetaPattern::Any(pattern) => pattern.compile(code, lits, captures),
52            MetaPattern::And(pattern) => pattern.compile(code, lits, captures),
53            MetaPattern::Or(pattern) => pattern.compile(code, lits, captures),
54            MetaPattern::Not(pattern) => pattern.compile(code, lits, captures),
55            MetaPattern::Repeat(pattern) => {
56                pattern.compile(code, lits, captures)
57            }
58            MetaPattern::Capture(pattern) => {
59                pattern.compile(code, lits, captures)
60            }
61            MetaPattern::Search(pattern) => {
62                pattern.compile(code, lits, captures)
63            }
64            MetaPattern::Sequence(pattern) => {
65                pattern.compile(code, lits, captures)
66            }
67        }
68    }
69
70    fn collect_capture_names(&self, names: &mut Vec<String>) {
71        match self {
72            MetaPattern::Any(pattern) => pattern.collect_capture_names(names),
73            MetaPattern::And(pattern) => pattern.collect_capture_names(names),
74            MetaPattern::Or(pattern) => pattern.collect_capture_names(names),
75            MetaPattern::Not(pattern) => pattern.collect_capture_names(names),
76            MetaPattern::Repeat(pattern) => {
77                pattern.collect_capture_names(names)
78            }
79            MetaPattern::Capture(pattern) => {
80                pattern.collect_capture_names(names)
81            }
82            MetaPattern::Search(pattern) => {
83                pattern.collect_capture_names(names)
84            }
85            MetaPattern::Sequence(pattern) => {
86                pattern.collect_capture_names(names)
87            }
88        }
89    }
90
91    fn is_complex(&self) -> bool {
92        match self {
93            MetaPattern::Any(pattern) => pattern.is_complex(),
94            MetaPattern::And(pattern) => pattern.is_complex(),
95            MetaPattern::Or(pattern) => pattern.is_complex(),
96            MetaPattern::Not(pattern) => pattern.is_complex(),
97            MetaPattern::Repeat(pattern) => pattern.is_complex(),
98            MetaPattern::Capture(pattern) => pattern.is_complex(),
99            MetaPattern::Search(pattern) => pattern.is_complex(),
100            MetaPattern::Sequence(pattern) => pattern.is_complex(),
101        }
102    }
103
104    fn paths_with_captures(
105        &self,
106        haystack: &CBOR,
107    ) -> (Vec<Path>, std::collections::HashMap<String, Vec<Path>>) {
108        match self {
109            MetaPattern::Any(pattern) => pattern.paths_with_captures(haystack),
110            MetaPattern::And(pattern) => pattern.paths_with_captures(haystack),
111            MetaPattern::Or(pattern) => pattern.paths_with_captures(haystack),
112            MetaPattern::Not(pattern) => pattern.paths_with_captures(haystack),
113            MetaPattern::Repeat(pattern) => pattern.paths_with_captures(haystack),
114            MetaPattern::Capture(pattern) => pattern.paths_with_captures(haystack),
115            MetaPattern::Search(pattern) => pattern.paths_with_captures(haystack),
116            MetaPattern::Sequence(pattern) => pattern.paths_with_captures(haystack),
117        }
118    }
119}
120
121impl std::fmt::Display for MetaPattern {
122    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123        match self {
124            MetaPattern::Any(pattern) => pattern.fmt(f),
125            MetaPattern::And(pattern) => pattern.fmt(f),
126            MetaPattern::Or(pattern) => pattern.fmt(f),
127            MetaPattern::Not(pattern) => pattern.fmt(f),
128            MetaPattern::Repeat(pattern) => pattern.fmt(f),
129            MetaPattern::Capture(pattern) => pattern.fmt(f),
130            MetaPattern::Search(pattern) => pattern.fmt(f),
131            MetaPattern::Sequence(pattern) => pattern.fmt(f),
132        }
133    }
134}