msg_auth_status/parser/auth_results/ptypes/spf/
spf_property_key.rs

1//! Parsing spf property types & values
2
3use crate::error::AuthResultsError;
4
5/// IANA Email Authentication Methods ptype / property Mapping stages
6#[derive(Debug, PartialEq)]
7pub enum SpfSmtpPropertyKey {
8    MailFrom,
9    Helo,
10}
11
12impl<'hdr> TryFrom<SpfSmtpPropertyKeyToken<'hdr>> for SpfSmtpPropertyKey {
13    type Error = AuthResultsError<'hdr>;
14    fn try_from(token: SpfSmtpPropertyKeyToken<'hdr>) -> Result<Self, Self::Error> {
15        let okk = match token {
16            SpfSmtpPropertyKeyToken::MailFrom => Self::MailFrom,
17            SpfSmtpPropertyKeyToken::Helo => Self::Helo,
18            _ => return Err(AuthResultsError::ParsePtypeBugInvalidProperty),
19        };
20        Ok(okk)
21    }
22}
23
24//----------
25// Parsing spf property
26//----------
27
28use super::{parse_comment, CommentToken};
29
30use logos::{Lexer, Logos};
31
32#[derive(Debug, Logos)]
33pub enum SpfSmtpPropertyKeyToken<'hdr> {
34    #[token("mailfrom", priority = 1)]
35    MailFrom,
36
37    #[token("helo", priority = 1)]
38    Helo,
39
40    #[token("(", priority = 2)]
41    CommentStart,
42
43    #[regex(r"\s+", |lex| lex.slice(), priority = 6)]
44    WhiteSpaces(&'hdr str),
45}
46
47pub fn parse_spf_smtp_property_key<'hdr>(
48    lexer: &mut Lexer<'hdr, SpfSmtpPropertyKeyToken<'hdr>>,
49) -> Result<SpfSmtpPropertyKey, AuthResultsError<'hdr>> {
50    while let Some(token) = lexer.next() {
51        match token {
52            Ok(SpfSmtpPropertyKeyToken::MailFrom | SpfSmtpPropertyKeyToken::Helo) => {
53                let property = token.map_err(|_| AuthResultsError::ParsePtypeBugPropertyGating)?;
54                let mapped_property_res: Result<SpfSmtpPropertyKey, AuthResultsError<'hdr>> =
55                    property.try_into();
56                let mapped_property = mapped_property_res
57                    .map_err(|_| AuthResultsError::ParsePtypeBugInvalidProperty)?;
58                return Ok(mapped_property);
59            }
60            Ok(SpfSmtpPropertyKeyToken::WhiteSpaces(_)) => {
61                // cont
62            }
63            Ok(SpfSmtpPropertyKeyToken::CommentStart) => {
64                let mut comment_lexer = CommentToken::lexer(lexer.remainder());
65                match parse_comment(&mut comment_lexer) {
66                    Ok(_comment) => {}
67                    Err(e) => return Err(AuthResultsError::ParseComment(e)),
68                }
69                lexer.bump(comment_lexer.span().end);
70            }
71            _ => {
72                let cut_slice = &lexer.source()[lexer.span().start..];
73                let cut_span = &lexer.source()[lexer.span().start..lexer.span().end];
74
75                let detail = crate::error::ParsingDetail {
76                    component: "spf_property_key",
77                    span_start: lexer.span().start,
78                    span_end: lexer.span().end,
79                    source: lexer.source(),
80                    clipped_span: cut_span,
81                    clipped_remaining: cut_slice,
82                };
83                return Err(AuthResultsError::ParsingDetailed(detail));
84            }
85        }
86    }
87    Err(AuthResultsError::RunAwaySpfPropertyKey)
88}