1#![warn(missing_docs)]
3use regex::Regex;
4use std::collections::HashMap;
5use std::io::BufRead;
6pub fn count(input: impl BufRead, option: CountOption) -> HashMap<String, usize> {
10 let re = Regex::new(r"\w+").unwrap();
11 let mut fregs = HashMap::new();
12 for line in input.lines() {
13 use crate::CountOption::*;
14 let line = line.unwrap();
15 match option {
16 Char => {
17 for c in line.chars() {
18 *fregs.entry(c.to_string()).or_insert(0) += 1;
19 }
20 },
21 Word => {
22 for m in re.find_iter(&line) {
23 let word = m.as_str().to_string();
24 *fregs.entry(word).or_insert(0) += 1;
25 }
26 },
27 Line => {
28 *fregs.entry(line.to_string()).or_insert(0) += 1;
29 }
30 }
31 }
32 fregs
33}
34#[derive(Debug,Clone,Copy,PartialEq,Eq,Hash)]
36pub enum CountOption {
37 Char,
39 Word,
41 Line,
43}
44impl Default for CountOption {
45 fn default() -> Self {
46 CountOption::Word
47 }
48}
49
50#[test]
51fn word_count_works() {
52 use std::io::Cursor;
53 let mut exp = HashMap::new();
54 exp.insert("aa".to_string(),1);
55 exp.insert("bb".to_string(),2);
56 assert_eq!(count(Cursor::new("aa bb bb"),CountOption::Word),exp);
57}
58