bytes
This commit is contained in:
parent
e212f048ef
commit
04a6d45802
4 changed files with 116 additions and 38 deletions
|
@ -1,3 +1,5 @@
|
|||
#![allow(non_snake_case, dead_code)]
|
||||
|
||||
mod prelude;
|
||||
mod rfc2234;
|
||||
mod rfc3501;
|
||||
|
|
37
imap/src/proto/prelude.rs
Normal file
37
imap/src/proto/prelude.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use std::ops::RangeFrom;
|
||||
|
||||
use nom::{
|
||||
error::{ErrorKind, ParseError},
|
||||
Err, IResult, InputIter, Needed, Parser, Slice,
|
||||
};
|
||||
|
||||
pub fn skip<E, F, I: Clone, O>(mut f: F) -> impl FnMut(I) -> IResult<I, (), E>
|
||||
where
|
||||
F: Parser<I, O, E>,
|
||||
{
|
||||
move |i: I| match f.parse(i.clone()) {
|
||||
Ok(_) => Ok((i, ())),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn satisfy<F, I, E, T>(f: F) -> impl Fn(I) -> IResult<I, T, E>
|
||||
where
|
||||
I: Slice<RangeFrom<usize>> + InputIter<Item = T>,
|
||||
F: Fn(T) -> bool,
|
||||
E: ParseError<I>,
|
||||
T: Copy,
|
||||
{
|
||||
move |i: I| match i.iter_elements().next().map(|t| (f(t), t)) {
|
||||
Some((true, ft)) => Ok((i.slice(1..), ft)),
|
||||
Some((false, _)) => Err(Err::Error(E::from_error_kind(i, ErrorKind::Satisfy))),
|
||||
None => Err(Err::Incomplete(Needed::Unknown)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn byte<I, E: ParseError<I>>(b: u8) -> impl Fn(I) -> IResult<I, u8, E>
|
||||
where
|
||||
I: Slice<RangeFrom<usize>> + InputIter<Item = u8>,
|
||||
{
|
||||
satisfy(move |c| c == b)
|
||||
}
|
|
@ -2,64 +2,56 @@
|
|||
|
||||
use nom::{
|
||||
branch::alt,
|
||||
character::streaming::{anychar, char, satisfy},
|
||||
character::streaming::{anychar},
|
||||
multi::many0,
|
||||
sequence::pair,
|
||||
IResult, Parser,
|
||||
IResult,
|
||||
};
|
||||
|
||||
pub fn skip<E, F, I: Clone, O>(mut f: F) -> impl FnMut(I) -> IResult<I, (), E>
|
||||
where
|
||||
F: Parser<I, O, E>,
|
||||
{
|
||||
move |i: I| match f.parse(i.clone()) {
|
||||
Ok(_) => Ok((i, ())),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
use super::prelude::{satisfy, skip, byte};
|
||||
|
||||
pub fn ALPHA(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
satisfy(|c| (c >= b'a' && c <= b'z') || (c >= b'A' && c <= b'Z'))(i)
|
||||
}
|
||||
|
||||
pub fn ALPHA(i: &[u8]) -> IResult<&[u8], char> {
|
||||
satisfy(|c| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))(i)
|
||||
pub fn BIT(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
satisfy(|c| c == b'0' || c == b'1')(i)
|
||||
}
|
||||
|
||||
pub fn BIT(i: &[u8]) -> IResult<&[u8], char> {
|
||||
satisfy(|c| c == '0' || c == '1')(i)
|
||||
pub fn CHAR(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
satisfy(|c| c != b'\0')(i)
|
||||
}
|
||||
|
||||
pub fn CHAR(i: &[u8]) -> IResult<&[u8], char> {
|
||||
satisfy(|c| c != '\0')(i)
|
||||
pub fn CR(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
byte(b'\x0d')(i)
|
||||
}
|
||||
|
||||
pub fn CR(i: &[u8]) -> IResult<&[u8], char> {
|
||||
char('\x0d')(i)
|
||||
}
|
||||
|
||||
pub fn CRLF(i: &[u8]) -> IResult<&[u8], (char, char)> {
|
||||
pub fn CRLF(i: &[u8]) -> IResult<&[u8], (u8, u8)> {
|
||||
pair(CR, LF)(i)
|
||||
}
|
||||
|
||||
pub fn CTL(i: &[u8]) -> IResult<&[u8], char> {
|
||||
satisfy(|c| c <= '\x1f' || c == '\x7f')(i)
|
||||
pub fn CTL(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
satisfy(|c| c <= b'\x1f' || c == b'\x7f')(i)
|
||||
}
|
||||
|
||||
pub fn DIGIT(i: &[u8]) -> IResult<&[u8], char> {
|
||||
satisfy(|c| c >= '\x30' && c <= '\x39')(i)
|
||||
pub fn DIGIT(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
satisfy(|c| c >= b'\x30' && c <= b'\x39')(i)
|
||||
}
|
||||
|
||||
pub fn DQUOTE(i: &[u8]) -> IResult<&[u8], char> {
|
||||
char('\x22')(i)
|
||||
pub fn DQUOTE(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
byte(b'\x22')(i)
|
||||
}
|
||||
|
||||
pub fn HEXDIG(i: &[u8]) -> IResult<&[u8], char> {
|
||||
alt((DIGIT, satisfy(|c| c >= 'A' && c <= 'F')))(i)
|
||||
pub fn HEXDIG(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
alt((DIGIT, satisfy(|c| c >= b'A' && c <= b'F')))(i)
|
||||
}
|
||||
|
||||
pub fn HTAB(i: &[u8]) -> IResult<&[u8], char> {
|
||||
char('\x09')(i)
|
||||
pub fn HTAB(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
byte(b'\x09')(i)
|
||||
}
|
||||
|
||||
pub fn LF(i: &[u8]) -> IResult<&[u8], char> {
|
||||
char('\x0a')(i)
|
||||
pub fn LF(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
byte(b'\x0a')(i)
|
||||
}
|
||||
|
||||
pub fn LWSP(i: &[u8]) -> IResult<&[u8], ()> {
|
||||
|
@ -70,14 +62,14 @@ pub fn OCTET(i: &[u8]) -> IResult<&[u8], char> {
|
|||
anychar(i)
|
||||
}
|
||||
|
||||
pub fn SP(i: &[u8]) -> IResult<&[u8], char> {
|
||||
char('\x20')(i)
|
||||
pub fn SP(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
byte(b'\x20')(i)
|
||||
}
|
||||
|
||||
pub fn VCHAR(i: &[u8]) -> IResult<&[u8], char> {
|
||||
satisfy(|c| c >= '\x21' && c <= '\x7e')(i)
|
||||
pub fn VCHAR(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
satisfy(|c| c >= b'\x21' && c <= b'\x7e')(i)
|
||||
}
|
||||
|
||||
pub fn WSP(i: &[u8]) -> IResult<&[u8], char> {
|
||||
pub fn WSP(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
alt((SP, HTAB))(i)
|
||||
}
|
||||
|
|
|
@ -1,2 +1,49 @@
|
|||
//! Grammar from https://datatracker.ietf.org/doc/html/rfc3501#section-9
|
||||
|
||||
use nom::{
|
||||
branch::alt,
|
||||
bytes::streaming::{tag_no_case, take},
|
||||
character::streaming::char,
|
||||
combinator::{map, map_res},
|
||||
multi::{many0, many1},
|
||||
sequence::delimited,
|
||||
IResult,
|
||||
};
|
||||
|
||||
use super::rfc2234::{DIGIT, DQUOTE};
|
||||
|
||||
/// literal = "{" number "}" CRLF *CHAR8
|
||||
/// ; Number represents the number of CHAR8s
|
||||
pub fn literal(i: &[u8]) -> IResult<&[u8], Vec<u8>> {
|
||||
let mut length_of = delimited(char('{'), number, char('}'));
|
||||
let (i, length) = length_of(i)?;
|
||||
map(take(length), |s: &[u8]| s.to_vec())(i)
|
||||
}
|
||||
|
||||
pub fn nil(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
tag_no_case("NIL")(i)
|
||||
}
|
||||
|
||||
pub fn nstring(i: &[u8]) -> IResult<&[u8], Option<Vec<u8>>> {
|
||||
alt((map(string, Some), map(nil, |_| None)))(i)
|
||||
}
|
||||
|
||||
pub fn number(i: &[u8]) -> IResult<&[u8], u32> {
|
||||
map_res(map_res(many1(DIGIT), String::from_utf8), |s| s.parse::<u32>())(i)
|
||||
}
|
||||
|
||||
pub fn quoted(i: &[u8]) -> IResult<&[u8], Vec<u8>> {
|
||||
delimited(DQUOTE, many0(QUOTED_CHAR), DQUOTE)(i)
|
||||
}
|
||||
|
||||
pub fn QUOTED_CHAR(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn string(i: &[u8]) -> IResult<&[u8], Vec<u8>> {
|
||||
alt((quoted, literal))(i)
|
||||
}
|
||||
|
||||
pub fn TEXT_CHAR(i: &[u8]) -> IResult<&[u8], u8> {
|
||||
todo!()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue