bc_envelope_pattern/parse/
parse_pattern.rs

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