forked from meli/meli
1
Fork 0

melib/sieve.rs: add beginning of sieve parser

Concerns #153

Support filtering rules to move mails to folders #153 <https://git.meli.delivery/meli/meli/issues/153>
sieve
Manos Pitsidianakis 2022-12-26 21:23:52 +02:00
parent 2878bbb8c8
commit 3c847ad26a
3 changed files with 1096 additions and 2 deletions

View File

@ -110,6 +110,7 @@ pub use addressbook::*;
pub mod backends;
pub use backends::*;
mod collection;
pub mod sieve;
pub use collection::*;
pub mod conf;
pub use conf::*;

View File

@ -267,6 +267,76 @@ where
}
}
pub fn pairmutation<'a, P1, P2, R1, R2>(parser1: P1, parser2: P2) -> impl Parser<'a, (R1, R2)>
where
P1: Parser<'a, R1>,
P2: Parser<'a, R2>,
{
move |input| {
if let ok @ Ok(_) = parser1.parse(input).and_then(|(next_input, result1)| {
parser2
.parse(next_input)
.map(|(last_input, result2)| (last_input, (result1, result2)))
}) {
return ok;
}
parser2.parse(input).and_then(|(next_input, result1)| {
parser1
.parse(next_input)
.map(|(last_input, result2)| (last_input, (result2, result1)))
})
}
}
#[macro_export]
macro_rules! permutation {
($input:expr, $($field:tt, $t:ty, $parser:expr),*) => {{
'perm: {
struct PermStruct {
$($field: Option<$t>),*
}
let mut results = PermStruct {
$($field: None),*
};
let mut input = $input;
let mut left = 0;
$(_ = &$parser; left += 1;)*
let mut count = 1;
let mut finished = 0;
loop {
let mut any_success = false;
$(if results.$field.is_none() {
if let Ok((rest, res)) = $parser.parse(input) {
if !matches!(res, None) || count > left {
results.$field = Some(res);
finished += 1;
count = 1;
input = rest;
}
any_success = true;
}
})*
count += 1;
if !any_success {
break 'perm Err(input);
}
if finished == left || count >= 2*left {
break;
}
}
if finished != left {
break 'perm Err(input);
}
let PermStruct {
$($field),*
} = results;
Ok((input, ($($field.unwrap()),*)))
}
}}
}
pub fn prefix<'a, PN, P, R, RN>(pre: PN, parser: P) -> impl Parser<'a, R>
where
PN: Parser<'a, RN>,
@ -293,9 +363,14 @@ where
}
}
pub fn delimited<'a, PN, RN, P, R>(lparser: PN, mid: P, rparser: PN) -> impl Parser<'a, R>
pub fn delimited<'a, PNL, PNR, LN, RN, P, R>(
lparser: PNL,
mid: P,
rparser: PNR,
) -> impl Parser<'a, R>
where
PN: Parser<'a, RN>,
PNL: Parser<'a, LN>,
PNR: Parser<'a, RN>,
P: Parser<'a, R>,
{
move |input| {

1018
melib/src/sieve.rs 100644

File diff suppressed because it is too large Load Diff