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 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}