imap_proto/parser/
gmail.rs

1use std::borrow::Cow;
2
3use nom::branch::alt;
4use nom::bytes::streaming::tag_no_case;
5use nom::combinator::map;
6use nom::sequence::preceded;
7use nom::IResult;
8
9use crate::{AttributeValue, MailboxDatum};
10
11use super::core::{number_64, parenthesized_list, quoted_utf8};
12use super::rfc3501::flag;
13
14pub(crate) fn gmail_label_list(i: &[u8]) -> IResult<&[u8], Vec<Cow<'_, str>>> {
15    preceded(
16        tag_no_case("X-GM-LABELS "),
17        parenthesized_list(map(alt((flag, quoted_utf8)), Cow::Borrowed)),
18    )(i)
19}
20
21pub(crate) fn msg_att_gmail_labels(i: &[u8]) -> IResult<&[u8], AttributeValue<'_>> {
22    map(gmail_label_list, AttributeValue::GmailLabels)(i)
23}
24
25pub(crate) fn mailbox_data_gmail_labels(i: &[u8]) -> IResult<&[u8], MailboxDatum<'_>> {
26    map(gmail_label_list, MailboxDatum::GmailLabels)(i)
27}
28
29pub(crate) fn gmail_msgid(i: &[u8]) -> IResult<&[u8], u64> {
30    preceded(tag_no_case("X-GM-MSGID "), number_64)(i)
31}
32
33pub(crate) fn msg_att_gmail_msgid(i: &[u8]) -> IResult<&[u8], AttributeValue<'_>> {
34    map(gmail_msgid, AttributeValue::GmailMsgId)(i)
35}
36
37pub(crate) fn mailbox_data_gmail_msgid(i: &[u8]) -> IResult<&[u8], MailboxDatum<'_>> {
38    map(gmail_msgid, MailboxDatum::GmailMsgId)(i)
39}
40
41pub(crate) fn gmail_thrid(i: &[u8]) -> IResult<&[u8], u64> {
42    preceded(tag_no_case("X-GM-THRID "), number_64)(i)
43}
44
45pub(crate) fn msg_att_gmail_thrid(i: &[u8]) -> IResult<&[u8], AttributeValue<'_>> {
46    map(gmail_thrid, AttributeValue::GmailThrId)(i)
47}
48
49pub(crate) fn mailbox_data_gmail_thrid(i: &[u8]) -> IResult<&[u8], MailboxDatum<'_>> {
50    map(gmail_thrid, MailboxDatum::GmailThrId)(i)
51}
52
53#[cfg(test)]
54mod tests {
55    use crate::types::*;
56    #[test]
57    fn test_gmail_labels() {
58        let env = br#"X-GM-LABELS (\Inbox \Sent Important "Muy Importante") "#;
59        match super::msg_att_gmail_labels(env) {
60            Ok((_, AttributeValue::GmailLabels(labels))) => {
61                println!("{labels:?}");
62                assert_eq!(
63                    ["\\Inbox", "\\Sent", "Important", "Muy Importante"].to_vec(),
64                    labels
65                );
66            }
67            rsp => {
68                let e = rsp.unwrap_err();
69                if let nom::Err::Error(i) = &e {
70                    println!("{:?}", std::str::from_utf8(i.input));
71                }
72                panic!("unexpected response {e:?}");
73            }
74        }
75    }
76
77    #[test]
78    fn test_gmail_msgid() {
79        let env = br#"X-GM-MSGID 1278455344230334865 "#;
80        match super::msg_att_gmail_msgid(env) {
81            Ok((_, AttributeValue::GmailMsgId(msgid))) => {
82                println!("{msgid:?}");
83                assert_eq!(1278455344230334865u64, msgid);
84            }
85            rsp => {
86                let e = rsp.unwrap_err();
87                if let nom::Err::Error(i) = &e {
88                    println!("{:?}", std::str::from_utf8(i.input));
89                }
90                panic!("unexpected response {e:?}");
91            }
92        }
93    }
94
95    #[test]
96    fn test_gmail_thrid() {
97        let env = br#"X-GM-THRID 1278455344230334865 "#;
98        match super::msg_att_gmail_thrid(env) {
99            Ok((_, AttributeValue::GmailThrId(thrid))) => {
100                println!("{thrid:?}");
101                assert_eq!(1278455344230334865, thrid);
102            }
103            rsp => {
104                let e = rsp.unwrap_err();
105                if let nom::Err::Error(i) = &e {
106                    println!("{:?}", std::str::from_utf8(i.input));
107                }
108                panic!("unexpected response {e:?}");
109            }
110        }
111    }
112}