a
This commit is contained in:
parent
f5b076d54c
commit
b2c96c9f46
3 changed files with 37 additions and 8 deletions
|
@ -23,11 +23,12 @@ pub enum Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ResponseCode<'a> {
|
pub enum ResponseCode<'a> {
|
||||||
|
Alert,
|
||||||
Capabilities(Vec<Capability<'a>>),
|
Capabilities(Vec<Capability<'a>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Capability<'a> {
|
pub enum Capability<'a> {
|
||||||
Imap4rev1,
|
Imap4rev1,
|
||||||
Auth(Cow<'a, str>),
|
Auth(Cow<'a, [u8]>),
|
||||||
Atom(Cow<'a, str>),
|
Atom(Cow<'a, [u8]>),
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ rule!(pub BIT : u8 => satisfy(|c| c == b'0' || c == b'1'));
|
||||||
pub fn is_char(c: u8) -> bool { c != b'\0' }
|
pub fn is_char(c: u8) -> bool { c != b'\0' }
|
||||||
rule!(pub CHAR : u8 => satisfy(is_char));
|
rule!(pub CHAR : u8 => satisfy(is_char));
|
||||||
|
|
||||||
rule!(pub CR : u8 => byte(b'\x0d'));
|
pub fn is_cr(c: u8) -> bool { c == b'\x0d' }
|
||||||
|
rule!(pub CR : u8 => satisfy(is_cr));
|
||||||
|
|
||||||
rule!(pub CRLF : (u8, u8) => pair(CR, LF));
|
rule!(pub CRLF : (u8, u8) => pair(CR, LF));
|
||||||
|
|
||||||
|
@ -27,7 +28,8 @@ rule!(pub HEXDIG : u8 => alt((DIGIT, satisfy(|c| c >= b'A' && c <= b'F'))));
|
||||||
|
|
||||||
rule!(pub HTAB : u8 => byte(b'\x09'));
|
rule!(pub HTAB : u8 => byte(b'\x09'));
|
||||||
|
|
||||||
rule!(pub LF : u8 => byte(b'\x0a'));
|
pub fn is_lf(c: u8) -> bool { c == b'\x0a' }
|
||||||
|
rule!(pub LF : u8 => satisfy(is_lf));
|
||||||
|
|
||||||
rule!(pub LWSP : () => skip(many0(alt((skip(WSP), skip(pair(CRLF, WSP)))))));
|
rule!(pub LWSP : () => skip(many0(alt((skip(WSP), skip(pair(CRLF, WSP)))))));
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
//! Grammar from https://datatracker.ietf.org/doc/html/rfc3501#section-9
|
//! Grammar from https://datatracker.ietf.org/doc/html/rfc3501#section-9
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::streaming::{tag_no_case, take},
|
bytes::streaming::{tag_no_case, take_while1, take},
|
||||||
character::streaming::char,
|
character::streaming::char,
|
||||||
combinator::{map, map_res},
|
combinator::{map, map_res},
|
||||||
multi::{many0, many1},
|
multi::{many0, many1},
|
||||||
sequence::{delimited, terminated},
|
sequence::{delimited, pair, preceded, separated_pair, terminated},
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::parsers::satisfy;
|
use super::parsers::satisfy;
|
||||||
use super::rfc2234::{is_char, is_ctl, is_dquote, is_sp, CRLF, DIGIT, DQUOTE};
|
use super::response::{Capability, ResponseCode};
|
||||||
|
use super::rfc2234::{is_char, is_cr, is_ctl, is_dquote, is_lf, is_sp, CRLF, DIGIT, DQUOTE, SP};
|
||||||
|
|
||||||
rule!(pub astring : Vec<u8> => alt((many1(ASTRING_CHAR), string)));
|
rule!(pub astring : Vec<u8> => alt((many1(ASTRING_CHAR), string)));
|
||||||
|
|
||||||
|
@ -37,6 +40,21 @@ pub fn is_atom_specials(c: u8) -> bool {
|
||||||
}
|
}
|
||||||
rule!(pub atom_specials : u8 => satisfy(is_atom_specials));
|
rule!(pub atom_specials : u8 => satisfy(is_atom_specials));
|
||||||
|
|
||||||
|
rule!(pub auth_type : Vec<u8> => atom);
|
||||||
|
|
||||||
|
rule!(pub capability : Capability => alt((
|
||||||
|
map(preceded(tag_no_case("AUTH="), auth_type), |s| Capability::Auth(Cow::from(s))),
|
||||||
|
map(atom, |s| Capability::Atom(Cow::from(s))),
|
||||||
|
)));
|
||||||
|
|
||||||
|
rule!(pub capability_data : Vec<Capability> => preceded(tag_no_case("CAPABILITY"), {
|
||||||
|
map(separated_pair(
|
||||||
|
many0(preceded(SP, capability)),
|
||||||
|
pair(SP, tag_no_case("IMAP4rev1")),
|
||||||
|
many0(preceded(SP, capability))
|
||||||
|
), |(mut a, b)| { a.extend(b); a })
|
||||||
|
}));
|
||||||
|
|
||||||
pub fn is_list_wildcards(c: u8) -> bool { c == b'%' || c == b'*' }
|
pub fn is_list_wildcards(c: u8) -> bool { c == b'%' || c == b'*' }
|
||||||
rule!(pub list_wildcards : u8 => satisfy(is_list_wildcards));
|
rule!(pub list_wildcards : u8 => satisfy(is_list_wildcards));
|
||||||
|
|
||||||
|
@ -77,6 +95,14 @@ rule!(pub quoted_specials : u8 => satisfy(is_quoted_specials));
|
||||||
pub fn is_resp_specials(c: u8) -> bool { c == b']' }
|
pub fn is_resp_specials(c: u8) -> bool { c == b']' }
|
||||||
rule!(pub resp_specials : u8 => satisfy(is_resp_specials));
|
rule!(pub resp_specials : u8 => satisfy(is_resp_specials));
|
||||||
|
|
||||||
|
rule!(pub resp_text_code : ResponseCode => alt((
|
||||||
|
map(tag_no_case("ALERT"), |_| ResponseCode::Alert),
|
||||||
|
map(capability_data, ResponseCode::Capabilities),
|
||||||
|
)));
|
||||||
|
|
||||||
rule!(pub string : Vec<u8> => alt((quoted, literal)));
|
rule!(pub string : Vec<u8> => alt((quoted, literal)));
|
||||||
|
|
||||||
pub fn TEXT_CHAR(i: &[u8]) -> IResult<&[u8], u8> { todo!() }
|
rule!(pub text : &[u8] => take_while1(is_text_char));
|
||||||
|
|
||||||
|
pub fn is_text_char(c: u8) -> bool { is_char(c) && !is_cr(c) && !is_lf(c) }
|
||||||
|
rule!(pub TEXT_CHAR : u8 => satisfy(is_text_char));
|
||||||
|
|
Loading…
Reference in a new issue