msg_auth_status/parser/auth_results/
reason.rs

1use crate::error::AuthResultsError;
2
3use logos::{Lexer, Logos};
4
5#[derive(Debug, Logos)]
6pub enum ReasonToken<'hdr> {
7    #[regex(r#"([^"\\]|\\t|\\u|\\n|\\")*"#, |lex| lex.slice(), priority = 1)]
8    MaybeReason(&'hdr str),
9
10    #[token("\"", priority = 2)]
11    DoubleQuote,
12}
13
14pub fn parse_reason<'hdr>(
15    lexer: &mut Lexer<'hdr, ReasonToken<'hdr>>,
16) -> Result<&'hdr str, AuthResultsError<'hdr>> {
17    let mut res_reason: Option<&'hdr str> = None;
18
19    let mut started = false;
20
21    while let Some(token) = lexer.next() {
22        match token {
23            Ok(ReasonToken::MaybeReason(reason_str)) => {
24                res_reason = Some(reason_str);
25            }
26            Ok(ReasonToken::DoubleQuote) => {
27                started = match started {
28                    true => break,
29                    false => true,
30                };
31            }
32            _ => {
33                let cut_slice = &lexer.source()[lexer.span().start..];
34                let cut_span = &lexer.source()[lexer.span().start..lexer.span().end];
35
36                let detail = crate::error::ParsingDetail {
37                    component: "reason",
38                    span_start: lexer.span().start,
39                    span_end: lexer.span().end,
40                    source: lexer.source(),
41                    clipped_span: cut_span,
42                    clipped_remaining: cut_slice,
43                };
44                return Err(AuthResultsError::ParsingDetailed(detail));
45            }
46        }
47    }
48
49    match res_reason {
50        Some(v) => Ok(v),
51        None => Err(AuthResultsError::NoAssociatedReason),
52    }
53}