1use crate::{
2 Error, Result,
3 pattern::{
4 Matcher, Path, meta::MetaPattern, structure::StructurePattern,
5 value::ValuePattern, vm::Instr,
6 },
7};
8
9use dcbor::prelude::*;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum Pattern {
13 Value(ValuePattern),
14 Structure(StructurePattern),
15 Meta(MetaPattern),
16}
17
18impl Pattern {
19 pub fn any_bool() -> Self {
21 Pattern::Value(ValuePattern::Bool(
22 crate::pattern::value::BoolPattern::any(),
23 ))
24 }
25
26 pub fn bool(value: bool) -> Self {
28 Pattern::Value(ValuePattern::Bool(
29 crate::pattern::value::BoolPattern::value(value),
30 ))
31 }
32
33 pub fn any_number() -> Self {
35 Pattern::Value(ValuePattern::Number(
36 crate::pattern::value::NumberPattern::any(),
37 ))
38 }
39
40 pub fn number<T>(value: T) -> Self
42 where
43 T: Into<f64>,
44 {
45 Pattern::Value(ValuePattern::Number(
46 crate::pattern::value::NumberPattern::value(value),
47 ))
48 }
49
50 pub fn number_range<A>(range: std::ops::RangeInclusive<A>) -> Self
52 where
53 A: Into<f64> + Copy,
54 {
55 Pattern::Value(ValuePattern::Number(
56 crate::pattern::value::NumberPattern::range(range),
57 ))
58 }
59
60 pub fn number_greater_than<T>(value: T) -> Self
62 where
63 T: Into<f64>,
64 {
65 Pattern::Value(ValuePattern::Number(
66 crate::pattern::value::NumberPattern::greater_than(value),
67 ))
68 }
69
70 pub fn number_greater_than_or_equal<T>(value: T) -> Self
73 where
74 T: Into<f64>,
75 {
76 Pattern::Value(ValuePattern::Number(
77 crate::pattern::value::NumberPattern::greater_than_or_equal(value),
78 ))
79 }
80
81 pub fn number_less_than<T>(value: T) -> Self
83 where
84 T: Into<f64>,
85 {
86 Pattern::Value(ValuePattern::Number(
87 crate::pattern::value::NumberPattern::less_than(value),
88 ))
89 }
90
91 pub fn number_less_than_or_equal<T>(value: T) -> Self
94 where
95 T: Into<f64>,
96 {
97 Pattern::Value(ValuePattern::Number(
98 crate::pattern::value::NumberPattern::less_than_or_equal(value),
99 ))
100 }
101
102 pub fn number_nan() -> Self {
104 Pattern::Value(ValuePattern::Number(
105 crate::pattern::value::NumberPattern::nan(),
106 ))
107 }
108
109 pub fn number_infinity() -> Self {
111 Pattern::Value(ValuePattern::Number(
112 crate::pattern::value::NumberPattern::infinity(),
113 ))
114 }
115
116 pub fn number_neg_infinity() -> Self {
118 Pattern::Value(ValuePattern::Number(
119 crate::pattern::value::NumberPattern::neg_infinity(),
120 ))
121 }
122
123 pub fn any_text() -> Self {
125 Pattern::Value(ValuePattern::Text(
126 crate::pattern::value::TextPattern::any(),
127 ))
128 }
129
130 pub fn text<T: Into<String>>(value: T) -> Self {
132 Pattern::Value(ValuePattern::Text(
133 crate::pattern::value::TextPattern::value(value),
134 ))
135 }
136
137 pub fn text_regex(regex: regex::Regex) -> Self {
139 Pattern::Value(ValuePattern::Text(
140 crate::pattern::value::TextPattern::regex(regex),
141 ))
142 }
143
144 pub fn any_byte_string() -> Self {
146 Pattern::Value(ValuePattern::ByteString(
147 crate::pattern::value::ByteStringPattern::any(),
148 ))
149 }
150
151 pub fn byte_string(value: impl AsRef<[u8]>) -> Self {
153 Pattern::Value(ValuePattern::ByteString(
154 crate::pattern::value::ByteStringPattern::value(value),
155 ))
156 }
157
158 pub fn byte_string_regex(regex: regex::bytes::Regex) -> Self {
160 Pattern::Value(ValuePattern::ByteString(
161 crate::pattern::value::ByteStringPattern::regex(regex),
162 ))
163 }
164
165 pub fn any_date() -> Self {
167 Pattern::Value(ValuePattern::Date(
168 crate::pattern::value::DatePattern::any(),
169 ))
170 }
171
172 pub fn date(date: Date) -> Self {
174 Pattern::Value(ValuePattern::Date(
175 crate::pattern::value::DatePattern::value(date),
176 ))
177 }
178
179 pub fn date_range(range: std::ops::RangeInclusive<Date>) -> Self {
181 Pattern::Value(ValuePattern::Date(
182 crate::pattern::value::DatePattern::range(range),
183 ))
184 }
185
186 pub fn date_earliest(date: Date) -> Self {
189 Pattern::Value(ValuePattern::Date(
190 crate::pattern::value::DatePattern::earliest(date),
191 ))
192 }
193
194 pub fn date_latest(date: Date) -> Self {
197 Pattern::Value(ValuePattern::Date(
198 crate::pattern::value::DatePattern::latest(date),
199 ))
200 }
201
202 pub fn date_iso8601(iso_string: impl Into<String>) -> Self {
205 Pattern::Value(ValuePattern::Date(
206 crate::pattern::value::DatePattern::string(iso_string),
207 ))
208 }
209
210 pub fn date_regex(regex: regex::Regex) -> Self {
213 Pattern::Value(ValuePattern::Date(
214 crate::pattern::value::DatePattern::regex(regex),
215 ))
216 }
217
218 pub fn null() -> Self {
220 Pattern::Value(ValuePattern::Null(crate::pattern::value::NullPattern))
221 }
222
223 pub fn any_known_value() -> Self {
225 Pattern::Value(ValuePattern::KnownValue(
226 crate::pattern::value::KnownValuePattern::any(),
227 ))
228 }
229
230 pub fn known_value(value: known_values::KnownValue) -> Self {
232 Pattern::Value(ValuePattern::KnownValue(
233 crate::pattern::value::KnownValuePattern::value(value),
234 ))
235 }
236
237 pub fn known_value_named(name: impl Into<String>) -> Self {
239 Pattern::Value(ValuePattern::KnownValue(
240 crate::pattern::value::KnownValuePattern::named(name),
241 ))
242 }
243
244 pub fn known_value_regex(regex: regex::Regex) -> Self {
247 Pattern::Value(ValuePattern::KnownValue(
248 crate::pattern::value::KnownValuePattern::regex(regex),
249 ))
250 }
251
252 pub fn any_digest() -> Self {
256 Pattern::Value(ValuePattern::Digest(
257 crate::pattern::value::DigestPattern::any(),
258 ))
259 }
260
261 pub fn digest(digest: bc_components::Digest) -> Self {
263 Pattern::Value(ValuePattern::Digest(
264 crate::pattern::value::DigestPattern::digest(digest),
265 ))
266 }
267
268 pub fn digest_prefix(prefix: impl AsRef<[u8]>) -> Self {
270 Pattern::Value(ValuePattern::Digest(
271 crate::pattern::value::DigestPattern::prefix(prefix),
272 ))
273 }
274
275 pub fn digest_binary_regex(regex: regex::bytes::Regex) -> Self {
277 Pattern::Value(ValuePattern::Digest(
278 crate::pattern::value::DigestPattern::binary_regex(regex),
279 ))
280 }
281
282 pub fn any() -> Self {
284 Pattern::Meta(MetaPattern::Any(crate::pattern::meta::AnyPattern::new()))
285 }
286
287 pub fn and(patterns: Vec<Pattern>) -> Self {
289 Pattern::Meta(MetaPattern::And(crate::pattern::meta::AndPattern::new(
290 patterns,
291 )))
292 }
293
294 pub fn or(patterns: Vec<Pattern>) -> Self {
296 Pattern::Meta(MetaPattern::Or(crate::pattern::meta::OrPattern::new(
297 patterns,
298 )))
299 }
300
301 pub fn not_matching(pattern: Pattern) -> Self {
303 Pattern::Meta(MetaPattern::Not(crate::pattern::meta::NotPattern::new(
304 pattern,
305 )))
306 }
307
308 pub fn capture(name: impl AsRef<str>, pattern: Pattern) -> Self {
310 Pattern::Meta(MetaPattern::Capture(
311 crate::pattern::meta::CapturePattern::new(name, pattern),
312 ))
313 }
314
315 pub fn search(pattern: Pattern) -> Self {
318 Pattern::Meta(MetaPattern::Search(
319 crate::pattern::meta::SearchPattern::new(pattern),
320 ))
321 }
322
323 pub fn repeat(pattern: Pattern, quantifier: crate::Quantifier) -> Self {
325 Pattern::Meta(MetaPattern::Repeat(
326 crate::pattern::meta::RepeatPattern::repeat(pattern, quantifier),
327 ))
328 }
329
330 pub fn group(pattern: Pattern) -> Self {
332 Pattern::Meta(MetaPattern::Repeat(
333 crate::pattern::meta::RepeatPattern::new(pattern),
334 ))
335 }
336
337 pub fn sequence(patterns: Vec<Pattern>) -> Self {
339 Pattern::Meta(MetaPattern::Sequence(
340 crate::pattern::meta::SequencePattern::new(patterns),
341 ))
342 }
343
344 pub fn any_array() -> Self {
346 Pattern::Structure(crate::pattern::structure::StructurePattern::Array(
347 crate::pattern::structure::ArrayPattern::any(),
348 ))
349 }
350
351 pub fn any_map() -> Self {
353 Pattern::Structure(crate::pattern::structure::StructurePattern::Map(
354 crate::pattern::structure::MapPattern::any(),
355 ))
356 }
357}
358
359
360impl Pattern {
361 pub fn any_tagged() -> Self {
363 Pattern::Structure(crate::pattern::structure::StructurePattern::Tagged(
364 crate::pattern::structure::TaggedPattern::any(),
365 ))
366 }
367
368 pub fn tagged(tag: impl Into<Tag>, pattern: Pattern) -> Self {
370 Pattern::Structure(crate::pattern::structure::StructurePattern::Tagged(
371 crate::pattern::structure::TaggedPattern::with_tag(tag, pattern),
372 ))
373 }
374
375 pub fn tagged_name(name: impl Into<String>, pattern: Pattern) -> Self {
378 Pattern::Structure(crate::pattern::structure::StructurePattern::Tagged(
379 crate::pattern::structure::TaggedPattern::with_name(name, pattern),
380 ))
381 }
382
383 pub fn tagged_regex(regex: regex::Regex, pattern: Pattern) -> Self {
386 Pattern::Structure(crate::pattern::structure::StructurePattern::Tagged(
387 crate::pattern::structure::TaggedPattern::with_regex(regex, pattern),
388 ))
389 }
390}
391
392impl Pattern {
393 pub fn parse(input: &str) -> Result<Self> {
412 let (pattern, consumed) = Self::parse_partial(input)?;
413 if consumed < input.len() {
414 return Err(Error::ExtraData(consumed..input.len()));
416 }
417 Ok(pattern)
418 }
419
420 pub fn parse_partial(input: &str) -> Result<(Self, usize)> {
436 use logos::Logos;
437
438 use crate::parse::{Token, meta::parse_or};
439
440 let mut lexer = Token::lexer(input);
441 let pattern = parse_or(&mut lexer)?;
442
443 let consumed = match lexer.next() {
445 Some(_) => lexer.span().start,
446 None => input.len(),
447 };
448
449 Ok((pattern, consumed))
450 }
451}
452
453impl TryFrom<&str> for Pattern {
454 type Error = Error;
455
456 fn try_from(value: &str) -> Result<Self> {
457 Self::parse(value)
458 }
459}
460
461impl Matcher for Pattern {
462 fn paths_with_captures(
463 &self,
464 haystack: &CBOR,
465 ) -> (Vec<Path>, std::collections::HashMap<String, Vec<Path>>) {
466 let mut capture_names = Vec::new();
468 self.collect_capture_names(&mut capture_names);
469
470 if capture_names.is_empty() {
472 return (self.paths(haystack), std::collections::HashMap::new());
473 }
474
475 match self {
478 Pattern::Meta(pattern) => {
479 return pattern.paths_with_captures(haystack);
482 }
483 Pattern::Structure(pattern) => {
484 return pattern.paths_with_captures(haystack);
487 }
488 _ => {
489 }
491 }
492
493 let mut code = Vec::new();
495 let mut literals = Vec::new();
496 let mut captures = Vec::new();
497
498 self.compile(&mut code, &mut literals, &mut captures);
499 code.push(crate::pattern::vm::Instr::Accept);
500
501 let program = crate::pattern::vm::Program {
502 code,
503 literals,
504 capture_names: captures,
505 };
506
507 crate::pattern::vm::run(&program, haystack)
509 }
510
511 fn paths(&self, haystack: &CBOR) -> Vec<Path> {
512 match self {
513 Pattern::Value(pattern) => pattern.paths(haystack),
514 Pattern::Structure(pattern) => pattern.paths(haystack),
515 Pattern::Meta(pattern) => pattern.paths(haystack),
516 }
517 }
518
519 fn compile(
520 &self,
521 code: &mut Vec<Instr>,
522 literals: &mut Vec<Pattern>,
523 captures: &mut Vec<String>,
524 ) {
525 match self {
526 Pattern::Value(pattern) => {
527 pattern.compile(code, literals, captures);
528 }
529 Pattern::Structure(pattern) => {
530 pattern.compile(code, literals, captures);
531 }
532 Pattern::Meta(pattern) => {
533 pattern.compile(code, literals, captures);
534 }
535 }
536 }
537
538 fn collect_capture_names(&self, names: &mut Vec<String>) {
540 match self {
541 Pattern::Value(_) => {
542 }
544 Pattern::Structure(pattern) => {
545 pattern.collect_capture_names(names);
546 }
547 Pattern::Meta(pattern) => {
548 pattern.collect_capture_names(names);
549 }
550 }
551 }
552
553 fn is_complex(&self) -> bool {
554 match self {
555 Pattern::Value(pattern) => pattern.is_complex(),
556 Pattern::Structure(_pattern) => false, Pattern::Meta(pattern) => pattern.is_complex(),
559 }
560 }
561}
562
563impl std::fmt::Display for Pattern {
564 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
565 match self {
566 Pattern::Value(pattern) => write!(f, "{}", pattern),
567 Pattern::Structure(pattern) => write!(f, "{}", pattern),
568 Pattern::Meta(pattern) => write!(f, "{}", pattern),
569 }
570 }
571}