dcbor_pattern/pattern/meta/
capture_pattern.rs1use dcbor::prelude::*;
2
3use crate::pattern::{Matcher, Path, Pattern, vm::Instr};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct CapturePattern {
12 name: String,
13 pattern: Box<Pattern>,
14}
15
16impl CapturePattern {
17 pub fn new(name: impl AsRef<str>, pattern: Pattern) -> Self {
19 CapturePattern {
20 name: name.as_ref().to_string(),
21 pattern: Box::new(pattern),
22 }
23 }
24
25 pub fn name(&self) -> &str { &self.name }
27
28 pub fn pattern(&self) -> &Pattern { &self.pattern }
30}
31
32impl Matcher for CapturePattern {
33 fn paths(&self, haystack: &CBOR) -> Vec<Path> {
34 self.pattern.paths(haystack)
38 }
39
40 fn compile(
41 &self,
42 code: &mut Vec<Instr>,
43 literals: &mut Vec<Pattern>,
44 captures: &mut Vec<String>,
45 ) {
46 let capture_idx = captures.len();
48 captures.push(self.name.clone());
49
50 code.push(Instr::CaptureStart(capture_idx));
52
53 self.pattern.compile(code, literals, captures);
55
56 code.push(Instr::CaptureEnd(capture_idx));
58 }
59
60 fn collect_capture_names(&self, names: &mut Vec<String>) {
61 names.push(self.name.clone());
63
64 self.pattern.collect_capture_names(names);
66 }
67
68 fn is_complex(&self) -> bool {
69 self.pattern.is_complex()
71 }
72
73 fn paths_with_captures(
74 &self,
75 haystack: &CBOR,
76 ) -> (Vec<Path>, std::collections::HashMap<String, Vec<Path>>) {
77 let (paths, mut captures) = self.pattern.paths_with_captures(haystack);
79
80 if !paths.is_empty() {
82 captures.insert(self.name.clone(), paths.clone());
83 }
84
85 (paths, captures)
86 }
87}
88
89impl std::fmt::Display for CapturePattern {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 write!(f, "@{}({})", self.name, self.pattern)
92 }
93}