sequoia_openpgp/cert/parser/low_level/
mod.rs

1use lalrpop_util::ParseError;
2
3use crate::{
4    Error,
5    packet::Tag,
6};
7
8pub(crate) mod lexer;
9lalrpop_util::lalrpop_mod!(
10    #[allow(clippy::all)]
11    #[allow(unused_parens)]
12    grammar,
13    "/cert/parser/low_level/grammar.rs"
14);
15
16pub(crate) mod bundle;
17pub(crate) mod grammar_util;
18
19pub(crate) use self::lexer::Token;
20pub(crate) use self::lexer::Lexer;
21
22pub(crate) use self::grammar::CertParser;
23
24// Converts a ParseError<usize, Token, Error> to a
25// ParseError<usize, Tag, Error>.
26//
27// Justification: a Token is a tuple containing a Tag and a Packet.
28// This function essentially drops the Packet.  Dropping the packet was
29// necessary, because packets were not Sync, but Error, which we want
30// to convert ParseErrors to, was.  Since we don't need the packet in
31// general anyways, changing the Token to a Tag is a simple and
32// sufficient fix.  Unfortunately, this conversion is a bit ugly and
33// will break if lalrpop ever extends ParseError.
34//
35// This justification is no longer up-to-date because Packet is now
36// also Sync.  However, we didn't catch this when we made Packet Sync,
37// and now the justification is simply that CertParserError::Parser(_)
38// expects a Tag, not a Packet.  It is not public, so we could change
39// it.
40pub(crate) fn parse_error_downcast(e: ParseError<usize, Token, Error>)
41    -> ParseError<usize, Tag, Error>
42{
43    match e {
44        ParseError::UnrecognizedToken {
45            token: (start, t, end),
46            expected,
47        } => ParseError::UnrecognizedToken {
48            token: (start, t.into(), end),
49            expected,
50        },
51
52        ParseError::ExtraToken {
53            token: (start, t, end),
54        } => ParseError::ExtraToken {
55            token: (start, t.into(), end),
56        },
57
58        ParseError::InvalidToken { location }
59        => ParseError::InvalidToken { location },
60
61        ParseError::User { error }
62        => ParseError::User { error },
63
64        ParseError::UnrecognizedEof { location, expected }
65        => ParseError::UnrecognizedEof { location, expected },
66    }
67}
68
69pub(crate) fn parse_error_to_openpgp_error(e: ParseError<usize, Tag, Error>)
70    -> Error
71{
72    match e {
73        ParseError::User { error } => error,
74        e => Error::MalformedCert(format!("{}", e)),
75    }
76}
77
78/// Errors that CertValidator::check may return.
79#[derive(Debug, Clone)]
80pub enum CertParserError {
81    /// A parser error.
82    Parser(ParseError<usize, Tag, Error>),
83    /// An OpenPGP error.
84    OpenPGP(Error),
85}
86assert_send_and_sync!(CertParserError);
87
88impl From<CertParserError> for anyhow::Error {
89    fn from(err: CertParserError) -> Self {
90        match err {
91            CertParserError::Parser(p) => p.into(),
92            CertParserError::OpenPGP(p) => p.into(),
93        }
94    }
95}