summaryrefslogtreecommitdiffstats
path: root/src/mailstore.rs
blob: 49f911f54fd783510d2b0d0728583356ef1054f3 (plain)
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
118
119
120
use std::ops::Deref;
use std::path::PathBuf;
use std::iter::FromIterator;
use anyhow::Result;
use maildir::Maildir;
use maildir::MailEntry;
use mailparse::ParsedMail;

pub struct MailStore {
    new: Vec<Mail>,
    cur: Vec<Mail>,
}

impl MailStore {
    pub fn build_from_path(path: PathBuf) -> MailStoreBuilder {
        let md = Maildir::from(path);
        MailStoreBuilder {
            cur: Box::new(md.list_cur().map(|m| Mail::cur_from(m?))),
            new: Box::new(md.list_new().map(|m| Mail::new_from(m?))),
        }
    }

    pub fn new_mail(&self) -> &Vec<Mail> {
        &self.new
    }

    pub fn cur_mail(&self) -> &Vec<Mail> {
        &self.cur
    }
}


impl FromIterator<Mail> for MailStore {
    fn from_iter<T>(iter: T) -> Self
        where T: IntoIterator<Item = Mail>
    {
        let mut new = vec![];
        let mut cur = vec![];
        for mail in iter {
            if mail.is_new() {
                new.push(mail)
            } else if mail.is_cur() {
                cur.push(mail)
            } else {
                unreachable!("Not implemented yet, should not be reachable in current implementation")
            }
        }

        MailStore { new, cur }
    }
}

pub struct MailStoreBuilder {
    cur: Box<dyn Iterator<Item = Result<Mail>>>,
    new: Box<dyn Iterator<Item = Result<Mail>>>,
}

impl Iterator for MailStoreBuilder {
    type Item = Result<Mail>;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(next) = self.cur.next() {
            return Some(next)
        }

        self.new.next()
    }
}

#[derive(Clone, Debug)]
pub struct Mail {
    entry: MailEntry,
    parsed: ParsedMail,
    mailtype: MailType,
}

#[derive(Debug, Clone, Eq, PartialEq)]
enum MailType {
    Cur,
    New,
}

impl Mail {
    fn cur_from(mut entry: MailEntry) -> Result<Self> {
        Ok(Mail {
            parsed: entry.parsed()?,
            entry,
            mailtype: MailType::Cur,
        })
    }

    fn new_from(mut entry: MailEntry) -> Result<Self> {
        Ok(Mail {
            parsed: entry.parsed()?,
            entry,
            mailtype: MailType::New,
        })
    }

    pub fn parsed(&self) -> &ParsedMail {
        &self.parsed
    }

    pub fn is_new(&self) -> bool {
        self.mailtype == MailType::New
    }

    pub fn is_cur(&self) -> bool {
        self.mailtype == MailType::Cur
    }
}

impl Deref for Mail {
    type Target = MailEntry;

    fn deref(&self) -> &Self::Target {
        &self.entry
    }
}