Skip to main content

bc_envelope_pattern/parse/
mod.rs

1mod leaf;
2mod meta;
3mod structure;
4mod token;
5mod utils;
6
7use logos::Logos;
8pub use token::Token;
9
10use crate::{
11    DCBORPattern, Error, Pattern, Result,
12    dcbor_integration::convert_dcbor_pattern_to_envelope_pattern,
13};
14
15impl Pattern {
16    /// Parse a pattern expression.
17    pub fn parse(input: impl AsRef<str>) -> Result<Pattern> {
18        let input_str = input.as_ref();
19        let mut lexer = Token::lexer(input_str);
20
21        // Try envelope-pattern parsing first
22        match meta::parse_or(&mut lexer) {
23            Ok(pattern) => match lexer.next() {
24                None => Ok(pattern),
25                Some(Ok(_)) => Err(Error::ExtraData(lexer.span())),
26                Some(Err(e)) => match e {
27                    Error::Unknown => {
28                        Err(Error::UnrecognizedToken(lexer.span()))
29                    }
30                    _ => Err(e),
31                },
32            },
33            Err(_envelope_error) => {
34                // If envelope-pattern parsing failed, try dcbor-pattern as
35                // fallback
36                match DCBORPattern::parse(input_str) {
37                    Ok(dcbor_pattern) => {
38                        convert_dcbor_pattern_to_envelope_pattern(dcbor_pattern)
39                    }
40                    Err(_dcbor_error) => {
41                        // Both parsers failed, return the original envelope
42                        // error
43                        Err(_envelope_error)
44                    }
45                }
46            }
47        }
48    }
49}
50
51impl TryFrom<&str> for Pattern {
52    type Error = Error;
53
54    fn try_from(value: &str) -> Result<Self> { Self::parse(value) }
55}