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
116
117
use std::io;
use stream::entry::header;
use super::Header;
bitflags! {
pub struct Status: u8 {
const NEW = 0b00000001;
const SEEN = 0b00000010;
const OLD = 0b00000100;
const ANSWERED = 0b00001000;
const FLAGGED = 0b00010000;
const DRAFT = 0b00100000;
const DELETED = 0b01000000;
}
}
impl Header for Status {
#[inline]
fn name() -> &'static str {
"Status"
}
#[inline]
fn parse(values: &[header::Item]) -> io::Result<Self> {
let mut status = Status::empty();
for ch in values[0].chars() {
status |= match ch {
'N' => NEW,
'R' => SEEN,
'O' => OLD,
'A' => ANSWERED,
'F' => FLAGGED,
'T' => DRAFT,
'D' => DELETED,
_ =>
return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid status"))
}
}
Ok(status)
}
}
#[cfg(test)]
mod test {
use super::*;
use stream::entry::header;
use header::Header;
macro_rules! parse {
($str:expr) => (
<Status as Header>::parse(&[header::item($str)])
);
}
#[test]
fn new() {
assert_eq!(parse!("N").unwrap(), NEW);
}
#[test]
fn read() {
assert_eq!(parse!("R").unwrap(), SEEN);
}
#[test]
fn old() {
assert_eq!(parse!("O").unwrap(), OLD);
}
#[test]
fn answered() {
assert_eq!(parse!("A").unwrap(), ANSWERED);
}
#[test]
fn flagged() {
assert_eq!(parse!("F").unwrap(), FLAGGED);
}
#[test]
fn draft() {
assert_eq!(parse!("T").unwrap(), DRAFT);
}
#[test]
fn deleted() {
assert_eq!(parse!("D").unwrap(), DELETED);
}
#[test]
fn mixed() {
assert_eq!(parse!("ROD").unwrap(), SEEN | OLD | DELETED);
assert_eq!(parse!("FTA").unwrap(), FLAGGED | DRAFT | ANSWERED);
}
#[test]
fn fail() {
assert!(parse!("ANTANI").is_err());
}
}