imap_proto/parser/
rfc4314.rs1use std::borrow::Cow;
12
13use nom::{
14 bytes::streaming::tag_no_case,
15 character::complete::{space0, space1},
16 combinator::map,
17 multi::separated_list0,
18 sequence::{preceded, separated_pair, tuple},
19 IResult,
20};
21
22use crate::parser::core::astring_utf8;
23use crate::parser::rfc3501::mailbox;
24use crate::types::*;
25
26pub(crate) fn acl(i: &[u8]) -> IResult<&[u8], Response> {
31 let (rest, (_, _, mailbox, acls)) = tuple((
32 tag_no_case("ACL"),
33 space1,
34 map(mailbox, Cow::Borrowed),
35 acl_list,
36 ))(i)?;
37
38 Ok((rest, Response::Acl(Acl { mailbox, acls })))
39}
40
41fn acl_list(i: &[u8]) -> IResult<&[u8], Vec<AclEntry>> {
45 preceded(space0, separated_list0(space1, acl_entry))(i)
46}
47
48fn acl_entry(i: &[u8]) -> IResult<&[u8], AclEntry> {
52 let (rest, (identifier, rights)) = separated_pair(
53 map(astring_utf8, Cow::Borrowed),
54 space1,
55 map(astring_utf8, map_text_to_rights),
56 )(i)?;
57
58 Ok((rest, AclEntry { identifier, rights }))
59}
60
61pub(crate) fn list_rights(i: &[u8]) -> IResult<&[u8], Response> {
66 let (rest, (_, _, mailbox, _, identifier, _, required, optional)) = tuple((
67 tag_no_case("LISTRIGHTS"),
68 space1,
69 map(mailbox, Cow::Borrowed),
70 space1,
71 map(astring_utf8, Cow::Borrowed),
72 space1,
73 map(astring_utf8, map_text_to_rights),
74 list_rights_optional,
75 ))(i)?;
76
77 Ok((
78 rest,
79 Response::ListRights(ListRights {
80 mailbox,
81 identifier,
82 required,
83 optional,
84 }),
85 ))
86}
87
88fn list_rights_optional(i: &[u8]) -> IResult<&[u8], Vec<AclRight>> {
89 let (rest, items) = preceded(space0, separated_list0(space1, astring_utf8))(i)?;
90
91 Ok((
92 rest,
93 items
94 .into_iter()
95 .flat_map(|s| s.chars().map(|c| c.into()))
96 .collect(),
97 ))
98}
99
100pub(crate) fn my_rights(i: &[u8]) -> IResult<&[u8], Response> {
105 let (rest, (_, _, mailbox, _, rights)) = tuple((
106 tag_no_case("MYRIGHTS"),
107 space1,
108 map(mailbox, Cow::Borrowed),
109 space1,
110 map(astring_utf8, map_text_to_rights),
111 ))(i)?;
112
113 Ok((rest, Response::MyRights(MyRights { mailbox, rights })))
114}
115
116fn map_text_to_rights(i: &str) -> Vec<AclRight> {
118 i.chars().map(|c| c.into()).collect()
119}