use std::collections::HashMap;
use std::io::Write;
use std::{io, str};
const SW_VERSION: &str = "0.0.12";
fn main() {
let mut company: HashMap<String, Vec<String>> = HashMap::new();
println!("Welcome to HR management SW v{SW_VERSION}. Write your instructions after >>.");
loop {
print!(">> ");
// flusing the stdout for showing the >>. I am not checking the Err
io::stdout().flush().unwrap();
let mut user_input = String::new();
match io::stdin().read_line(&mut user_input) {
Ok(n) => {
user_input = user_input.trim().to_string();
// println!("Input: {n} bytes.");
let keywords: Vec<&str> = user_input.split_whitespace().collect();
match keywords.as_slice() {
["exit"] => {
println!("Closing the SW.");
break;
}
["help"] => show_help(),
["add", name, dep] => {
add_person(&mut company, name, dep);
println!("Added {name} to {}.", dep.to_uppercase());
}
["rm", name, dep] => match remove_person(&mut company, name, dep) {
Ok(()) => println!("{name} correctly removed from {}", dep.to_uppercase()),
Err(msg) => println!("{msg}"),
},
["list"] => match list_all_people(&company) {
Ok(()) => {}
Err(msg) => println!("{msg}"),
},
["list", dep] => match list_all_people_from_dep(&company, dep) {
Ok(()) => {}
Err(msg) => println!("{msg}"),
},
["add", ..] => println!(
"Error. Expected 'add <name> <department>. Type 'help' for further info."
),
["rm", ..] => println!(
"Error. Expected 'rm <name> <department>. Type 'help' for further info."
),
["list", ..] => {
println!("Error. Too many arguments. Type 'help' for further info.")
}
[] => println!(""),
_ => println!("Error. Type 'help' for further info."), // None => println!("Nothing to check."),
}
}
Err(error) => println!("Error: {error}"),
}
}
}
fn add_person(company: &mut HashMap<String, Vec<String>>, name: &str, dep: &str) {
company
.entry(dep.to_uppercase().to_string())
.or_default()
.push(name.to_string());
}
fn remove_person(
company: &mut HashMap<String, Vec<String>>,
name: &str,
dep: &str,
) -> Result<(), String> {
let dep_key = dep.to_uppercase();
if let Some(staff) = company.get_mut(&dep_key) {
for i in 0..staff.len() {
if staff[i] == name {
staff.remove(i);
return Ok(());
}
}
return Err(format!("{name} has not been found in {dep}."));
}
Err(format!("{dep} is not in the record."))
}
fn list_all_people(company: &HashMap<String, Vec<String>>) -> Result<(), String> {
let mut all_people: Vec<(&String, &String)> = Vec::new();
// creating vector
for (department, names) in company {
for name in names {
all_people.push((name, department));
}
}
// ordering vector. a0 is the name of a tuple, and b.0 the other name of the other tuple.
all_people.sort_by(|a, b| a.0.cmp(b.0));
if all_people.is_empty() {
return Err(format!("No employee in the company."));
}
for (name, department) in all_people {
println!("{} - {}", name, department);
}
Ok(())
}
fn list_all_people_from_dep(
company: &HashMap<String, Vec<String>>,
dep: &str,
) -> Result<(), String> {
match company.get(&dep.to_uppercase()) {
Some(people) => {
for i in people {
println!("- {i}");
}
return Ok(());
}
None => {
return Err(format!(
"The department {} does not exist.",
dep.to_uppercase()
));
}
}
}
fn show_help() {
println!("");
println!("HR Resource Management - v.{SW_VERSION}.");
println!("Insert 'add <name> <department> for adding an employee to the database.");
println!("Insert 'rm <name> <department> for removing an employee from the database.");
println!(
"Insert 'list' for lisitng all the employees in alphabetical order. The output is <name> - <department>."
);
println!(
"Insert 'list <department> for listing all the employess, in alphabetical order, from a departent."
);
println!("Insert 'exit' to quit.");
}