1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use abnf_core::streaming::SP;
use nom::{
branch::alt,
bytes::streaming::{tag, tag_no_case},
combinator::{map, value},
multi::{separated_list0, separated_list1},
sequence::{delimited, preceded},
IResult,
};
use crate::{
parse::core::atom,
types::{
core::atm,
flag::{Flag, FlagNameAttribute},
},
};
pub(crate) fn flag(input: &[u8]) -> IResult<&[u8], Flag> {
alt((
value(Flag::Answered, tag_no_case(b"\\Answered")),
value(Flag::Flagged, tag_no_case(b"\\Flagged")),
value(Flag::Deleted, tag_no_case(b"\\Deleted")),
value(Flag::Seen, tag_no_case(b"\\Seen")),
value(Flag::Draft, tag_no_case(b"\\Draft")),
flag_keyword,
map(flag_extension, |a| Flag::Extension(a.to_owned())),
))(input)
}
pub(crate) fn flag_fetch(input: &[u8]) -> IResult<&[u8], Flag> {
alt((flag, value(Flag::Recent, tag_no_case(b"\\Recent"))))(input)
}
pub(crate) fn flag_perm(input: &[u8]) -> IResult<&[u8], Flag> {
alt((flag, value(Flag::Permanent, tag(b"\\*"))))(input)
}
#[inline]
fn flag_keyword(input: &[u8]) -> IResult<&[u8], Flag> {
map(atom, |a| Flag::Keyword(a.to_owned()))(input)
}
pub(crate) fn flag_list(input: &[u8]) -> IResult<&[u8], Vec<Flag>> {
delimited(tag(b"("), separated_list0(SP, flag), tag(b")"))(input)
}
pub(crate) fn mbx_list_flags(input: &[u8]) -> IResult<&[u8], Vec<FlagNameAttribute>> {
let (remaining, flags) = separated_list1(SP, alt((mbx_list_sflag, mbx_list_oflag)))(input)?;
let sflag_count = flags
.iter()
.filter(|&flag| FlagNameAttribute::is_selectability(flag))
.count();
if sflag_count > 1 {
return Err(nom::Err::Error(nom::error::make_error(
input,
nom::error::ErrorKind::Verify,
)));
}
Ok((remaining, flags))
}
fn mbx_list_oflag(input: &[u8]) -> IResult<&[u8], FlagNameAttribute> {
alt((
value(
FlagNameAttribute::Noinferiors,
tag_no_case(b"\\Noinferiors"),
),
map(flag_extension, |a| {
FlagNameAttribute::Extension(a.to_owned())
}),
))(input)
}
fn mbx_list_sflag(input: &[u8]) -> IResult<&[u8], FlagNameAttribute> {
alt((
value(FlagNameAttribute::Noselect, tag_no_case(b"\\Noselect")),
value(FlagNameAttribute::Marked, tag_no_case(b"\\Marked")),
value(FlagNameAttribute::Unmarked, tag_no_case(b"\\Unmarked")),
))(input)
}
fn flag_extension(input: &[u8]) -> IResult<&[u8], atm> {
preceded(tag(b"\\"), atom)(input)
}