use std::{collections::HashMap, io::{Write, self}};
use std::fs;
fn main() -> Result<(), String> {
let file_path = match std::env::args().nth(1) {
Some(file_path) => file_path,
None => return Err(String::from("No file path specified.")),
};
let buf = match fs::read_to_string(file_path) {
Ok(string) => string,
Err(error) => return Err(error.to_string()),
};
let mut char_map = HashMap::new();
let mut char_vec : Vec<(char, usize)> = Vec::new();
for i in 0..256 {
char_vec.push((char::from_u32(i).unwrap(), 0));
}
let mut total_character_amount : usize = 0;
for char in buf.chars() {
if char.is_whitespace() { continue; }
if char.is_ascii() {
char_vec[char as usize].1 += 1;
total_character_amount += 1;
continue;
}
let mut array_pos : usize = char_vec.len();
match char_map.get(&char) {
Some(x) => (array_pos = *x),
None => {
match char_map.insert(char, array_pos) {
Some(_x) => (return Err(String::from("Char map inserted the same error twice!"))),
None => char_vec.push((char, 0)),
};
},
};
char_vec[array_pos].1 += 1;
total_character_amount += 1;
}
char_vec.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
let stdout = io::stdout();
let mut handle = io::BufWriter::new(stdout);
for val in char_vec {
if val.1 == 0 { continue; }
match writeln!(handle, "{} : {}\t{:.3}%", val.0, val.1, ((val.1 as f64 / total_character_amount as f64) * 100.0)) {
Ok(_) => (),
Err(error) => return Err(error.to_string()),
};
};
match writeln!(handle, "Total character amount {}", total_character_amount) {
Err(error) => return Err(error.to_string()),
_ => (),
};
match handle.flush() {
Err(error) => return Err(error.to_string()),
_ => (),
};
Ok(())
}