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.
```