As I'm learning Rust using the second edition of the Rust book I solved the following exercise:
Using a hash map and vectors, create a text interface to allow a user to add employee names to a department in a company. For example, “Add Sally to Engineering” or “Add Amir to Sales.” Then let the user retrieve a list of all people in a department or all people in the company by department, sorted alphabetically.
I could find this solution: Rust exercise department employee management (which did not receive a lot of feedback).
Do you have any feedback on my implementation? The code works, but I can imagine that some refactoring would be good. It already took me a lot of trial and error to get this working :-)
Suggestions welcome!
use std::io;
use std::collections::HashMap;
fn main() {
let mut employees:HashMap<String, Vec<String>> = HashMap::new();
println!("Start adding employees or type 'Done' when finished!");
loop {
let mut input = String::new();
io::stdin().read_line(&mut input).expect("error: unable to read user input");
let parsed_input = dissect_input(input.clone());
match parsed_input {
Ok(v) => {
let (dept, name) = v;
employees.entry(dept.to_string())
.or_insert_with(Vec::new)
.push(name)
}
Err(e) => {
if e == "End" {
println!("Processed all input, good!\n\n");
break;
} else {
println!("Input error!");
continue;
}
}
}
}
println!("Type the name of a department to get its employees.");
println!("Type 'All' to get all employees by department.");
println!("Type 'Quit' to quit.");
loop {
let mut command = String::new();
io::stdin().read_line(&mut command).expect("error: unable to read user input");
match command.trim() {
"Quit" => break,
"All" => {
for (dept, names) in &employees {
let mut names = names.clone();
names.sort();
for name in names {
println!("{}: {}", dept, name);
}
}
}
_ => {
match employees.get(&command.trim().to_string()) {
Some(names) => {
for name in names { println!("{}: {}", command.trim().to_string(), name); }
}
None => println!("I don't recognize that!")
}
}
}
}
println!("Have a nice day!");
}
fn dissect_input(s: String) -> Result<(String, String), String> {
match s.trim().as_ref() {
"Done" => Err("End".to_string()),
_ => {
let words: Vec<&str> = s.split_whitespace().collect();
if words.len() != 4 {
Err("PEBCAK".to_string())
} else {
Ok((words[3].to_string(), words[1].to_string())) // “Add Sally to Engineering”
}
}
}
}
// Using a hash map and vectors, create a text interface to allow a user
// to add employee names to a department in a company.
// For example, “Add Sally to Engineering” or “Add Amir to Sales.”
// Then let the user retrieve a list of all people in a department
// or all people in the company by department, sorted alphabetically.
```