diff options
author | Till Höppner | 2016-02-25 06:48:03 +0100 |
---|---|---|
committer | Till Höppner | 2016-02-25 06:48:03 +0100 |
commit | 9f5dd9dad6b13476bab2c6eb3c6528f8ad49311a (patch) | |
tree | 1ca71876029cb466aa6230f1aead05b32f19bf6d /ops/src/freq.rs | |
parent | 685aac1cc537692b2cf9342dcb6c26fa74c3c920 (diff) | |
download | ilc-9f5dd9dad6b13476bab2c6eb3c6528f8ad49311a.tar.gz ilc-9f5dd9dad6b13476bab2c6eb3c6528f8ad49311a.tar.xz ilc-9f5dd9dad6b13476bab2c6eb3c6528f8ad49311a.zip |
Refactor... everything.
Diffstat (limited to 'ops/src/freq.rs')
-rw-r--r-- | ops/src/freq.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/ops/src/freq.rs b/ops/src/freq.rs new file mode 100644 index 0000000..c5b363a --- /dev/null +++ b/ops/src/freq.rs @@ -0,0 +1,87 @@ +use ilc_base::{self, Context, Decode, Event}; +use ilc_base::event::Type; + +use std::collections::HashMap; +use std::io::{BufRead, Write}; + +struct Person { + lines: u32, + alpha_lines: u32, + words: u32, +} + +fn words_alpha(s: &str) -> (u32, bool) { + let mut alpha = false; + let mut words = 0; + for w in s.split_whitespace() { + if !w.is_empty() { + words += 1; + if w.chars().any(char::is_alphabetic) { + alpha = true + } + } + } + (words, alpha) +} + +fn strip_nick_prefix(s: &str) -> &str { + if s.is_empty() { + return s; + } + match s.as_bytes()[0] { + b'~' | b'&' | b'@' | b'%' | b'+' => &s[1..], + _ => s, + } +} + +// TODO: Don't print results, return Stats struct +pub fn freq(count: usize, + ctx: &Context, + input: &mut BufRead, + decoder: &mut Decode, + output: &mut Write) + -> ilc_base::Result<()> { + let mut stats: HashMap<String, Person> = HashMap::new(); + + for e in decoder.decode(&ctx, input) { + let m = try!(e); + match m { + Event { ty: Type::Msg { ref from, ref content, .. }, .. } => { + let nick = strip_nick_prefix(from); + if stats.contains_key(nick) { + let p: &mut Person = stats.get_mut(nick).unwrap(); + let (words, alpha) = words_alpha(content); + p.lines += 1; + if alpha { + p.alpha_lines += 1 + } + p.words += words; + } else { + let (words, alpha) = words_alpha(content); + stats.insert(nick.to_owned(), + Person { + lines: 1, + alpha_lines: if alpha { 1 } else { 0 }, + words: words, + }); + } + } + _ => (), + } + } + + let mut stats: Vec<(String, Person)> = stats.into_iter().collect(); + stats.sort_by(|&(_, ref a), &(_, ref b)| b.words.cmp(&a.words)); + + for &(ref name, ref stat) in stats.iter().take(count) { + try!(write!(output, + "{}:\n\tTotal lines: {}\n\tLines without alphabetic characters: {}\n\tTotal \ + words: {}\n\tWords per line: {}\n", + name, + stat.lines, + stat.lines - stat.alpha_lines, + stat.words, + stat.words as f32 / stat.lines as f32)); + } + Ok(()) +} |