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
use book::Book;
use text_view::view_as_text;
use style;
use std::fmt;
struct ChapterStats {
pub name: String,
pub word_count: usize,
pub char_count: usize,
}
pub struct Stats {
chapters: Vec<ChapterStats>,
}
impl Stats {
pub fn new(book: &Book) -> Stats {
let mut stats = Stats{
chapters: vec!(),
};
for c in &book.chapters {
let name = c.filename.clone();
let text = view_as_text(&c.content);
let wc = text.split_whitespace().count();
let cc = text.len();
stats.chapters.push(ChapterStats {
name: name,
word_count: wc,
char_count: cc
});
}
stats
}
}
impl fmt::Display for Stats {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:<30} {:>6} {:>7}\n---------\n",
style::header(&lformat!("Chapter")),
style::header(&lformat!("Words")),
style::header(&lformat!("Chars")))?;
for c in &self.chapters {
write!(f, "{:<30} {:>6} {:>7}\n",
style::element(&c.name),
c.word_count,
c.char_count)?;
}
let total = self.chapters
.iter()
.fold((0, 0), |acc, c| (acc.0 + c.word_count, acc.1 + c.char_count));
write!(f, "---------\n{:<30} {:>6} {:>7}\n",
style::element(&lformat!("TOTAL:")),
total.0,
total.1)
}
}