bmatcher_core/pattern.rs
1use alloc::vec::Vec;
2use core::fmt::Debug;
3
4use crate::Atom;
5
6/// A binary pattern is a structure used in matching processes and consists of two main components:
7///
8/// 1. Atoms
9/// A list of instructions or actions that define how the matcher should process the data at the current cursor.
10///
11/// 2. Byte Sequence
12/// A sequence of bytes that the atoms can reference to match against actual input data.
13pub trait BinaryPattern: Send + Sync + Debug {
14 /// Retrieves the list of atoms within this binary pattern.
15 ///
16 /// The atoms define the actions or matching logic for the pattern.
17 fn atoms(&self) -> &[Atom];
18
19 /// Retrieves the byte sequence referenced by the atoms.
20 ///
21 /// This sequence represents the actual data to be matched against.
22 fn byte_sequence(&self) -> &[u8];
23
24 /// Returns an upper bound for the length of the save stack.
25 ///
26 /// # Note
27 /// This is only an upper bound. The actual length used might be smaller.
28 fn save_len(&self) -> usize {
29 self.atoms()
30 .iter()
31 .filter(|atom| {
32 matches!(
33 atom,
34 Atom::Read(_) | Atom::SaveCursor | Atom::SaveConstant(_)
35 )
36 })
37 .count()
38 }
39
40 /// Returns an upper bound for the length of the cursor stack.
41 ///
42 /// # Note
43 /// This is only an upper bound. The actual length used might be smaller.
44 fn cursor_len(&self) -> usize {
45 self.atoms()
46 .iter()
47 .filter(|atom| matches!(atom, Atom::CursorPush))
48 .count()
49 }
50}
51
52/// An implementation of the [BinaryPattern] interface that borrows the [Atom]s and byte sequence array.
53///
54/// This struct is primarily used alongside the [bmatcher_proc::pattern] macro to generate patterns at runtime.
55#[derive(Debug, Clone, Copy)]
56pub struct BorrowedBinaryPattern<'a> {
57 atoms: &'a [Atom],
58 byte_sequence: &'a [u8],
59}
60
61impl<'a> BorrowedBinaryPattern<'a> {
62 pub const fn new(atoms: &'a [Atom], byte_sequence: &'a [u8]) -> Self {
63 Self {
64 atoms,
65 byte_sequence,
66 }
67 }
68}
69
70impl BinaryPattern for BorrowedBinaryPattern<'_> {
71 fn atoms(&self) -> &[Atom] {
72 self.atoms
73 }
74
75 fn byte_sequence(&self) -> &[u8] {
76 self.byte_sequence
77 }
78}
79
80/// An implementation of the [BinaryPattern] interface that allocates a `Vec` for the [Atom]s and the byte sequence.
81///
82/// This struct is primarily used with [crate::compiler::parse_pattern] to parse binary patterns at runtime.
83#[derive(Debug, Default)]
84pub struct OwnedBinaryPattern {
85 atoms: Vec<Atom>,
86 byte_sequence: Vec<u8>,
87}
88
89impl OwnedBinaryPattern {
90 pub fn new(atoms: Vec<Atom>, byte_sequence: Vec<u8>) -> Self {
91 Self {
92 byte_sequence,
93 atoms,
94 }
95 }
96}
97
98impl BinaryPattern for OwnedBinaryPattern {
99 fn byte_sequence(&self) -> &[u8] {
100 &self.byte_sequence
101 }
102
103 fn atoms(&self) -> &[Atom] {
104 &self.atoms
105 }
106}