cli_agenda/
lib.rs

1extern crate term;
2
3use std::fmt;
4use std::io::prelude::*;
5
6#[derive(Copy, Clone, Debug, Eq, PartialEq)]
7pub enum Progress {
8    Section,
9    Headline,
10    Item,
11    Bottom,
12}
13
14impl Progress {
15    pub fn enter<D: fmt::Display>(self, name: D) -> Self {
16        let mut t = term::stderr().unwrap();
17
18        match self {
19            Progress::Section => {
20                t.fg(term::color::BLUE).unwrap();
21                t.attr(term::Attr::Bold).unwrap();
22                write!(t, ":: ").unwrap();
23
24                t.reset().unwrap();
25                t.attr(term::Attr::Bold).unwrap();
26                writeln!(t, "{}", name).unwrap();
27
28                t.reset().unwrap();
29
30                Progress::Headline
31            }
32            Progress::Headline => {
33                t.fg(term::color::GREEN).unwrap();
34                t.attr(term::Attr::Bold).unwrap();
35                write!(t, "==> ").unwrap();
36
37                t.reset().unwrap();
38                t.attr(term::Attr::Bold).unwrap();
39                writeln!(t, "{}", name).unwrap();
40
41                t.reset().unwrap();
42
43                Progress::Item
44            }
45            Progress::Item | Progress::Bottom => {
46                t.fg(term::color::BLUE).unwrap();
47                t.attr(term::Attr::Bold).unwrap();
48                write!(t, "  -> ").unwrap();
49
50                t.reset().unwrap();
51                t.attr(term::Attr::Bold).unwrap();
52                writeln!(t, "{}", name).unwrap();
53
54                t.reset().unwrap();
55
56                Progress::Bottom
57            }
58        }
59    }
60
61    pub fn leave(self) -> Progress {
62        match self {
63            Progress::Bottom => Progress::Item,
64            Progress::Item => Progress::Headline,
65            Progress::Headline | Progress::Section => {
66                // empty line after section end
67                let mut t = term::stderr().unwrap();
68                writeln!(t, "").unwrap();
69
70                Progress::Section
71            }
72        }
73    }
74
75    pub fn root(mut self) -> Progress {
76        loop {
77            if let Progress::Section = self {
78                break self;
79            }
80            self = self.leave()
81        }
82    }
83
84    pub fn error<D: fmt::Display>(&self, msg: D) {
85        let mut t = term::stderr().unwrap();
86
87        match self {
88            Progress::Section => {
89                t.fg(term::color::RED).unwrap();
90                t.attr(term::Attr::Bold).unwrap();
91                writeln!(t, ":: ERROR: {}", msg).unwrap();
92                t.reset().unwrap();
93            }
94            Progress::Headline => {
95                t.fg(term::color::RED).unwrap();
96                t.attr(term::Attr::Bold).unwrap();
97                write!(t, "==> ERROR: ").unwrap();
98
99                t.reset().unwrap();
100                t.attr(term::Attr::Bold).unwrap();
101                writeln!(t, "{}", msg).unwrap();
102
103                t.reset().unwrap();
104            }
105            Progress::Item | Progress::Bottom => {
106                t.fg(term::color::RED).unwrap();
107                t.attr(term::Attr::Bold).unwrap();
108                writeln!(t, "  -> {}", msg).unwrap();
109                t.reset().unwrap();
110            }
111        }
112    }
113
114    pub fn warn<D: fmt::Display>(&self, msg: D) {
115        let mut t = term::stderr().unwrap();
116
117        match self {
118            Progress::Section => {
119                t.fg(term::color::YELLOW).unwrap();
120                t.attr(term::Attr::Bold).unwrap();
121                writeln!(t, ":: WARN: {}", msg).unwrap();
122                t.reset().unwrap();
123            }
124            Progress::Headline => {
125                t.fg(term::color::YELLOW).unwrap();
126                t.attr(term::Attr::Bold).unwrap();
127                write!(t, "==> WARN: ").unwrap();
128
129                t.reset().unwrap();
130                t.attr(term::Attr::Bold).unwrap();
131                writeln!(t, "{}", msg).unwrap();
132
133                t.reset().unwrap();
134            }
135            Progress::Item | Progress::Bottom => {
136                t.fg(term::color::YELLOW).unwrap();
137                t.attr(term::Attr::Bold).unwrap();
138                writeln!(t, "  -> {}", msg).unwrap();
139                t.reset().unwrap();
140            }
141        }
142    }
143
144    pub fn single<D: fmt::Display>(&self, name: D) {
145        self.clone().enter(name).leave();
146    }
147}
148
149pub fn start() -> Progress {
150    Progress::Section
151}
152
153#[cfg(test)]
154mod tests {
155    #[test]
156    fn it_works() {
157        assert_eq!(2 + 2, 4);
158    }
159}