HashMap exercise, Rust book Ch.8
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
4
down vote
favorite
I'm learning Rust by learning the Rust programming language book. I'm now implementing the solution for the third challenge.
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 decided to do a simple UI to enter commands, but the implementation is very naive overall.
Rust is my first systems language. My background is in Ruby and Javascript.
use std::collections::HashMap;
use std::io::self, Write;
use std::str::SplitWhitespace;
fn main()
println!("Welcome to the department interface. Please run a command:");
help();
let mut departments: HashMap<String, Vec<String>> = HashMap::new();
loop
print_promt();
let command = get_command();
let mut command_iter = command.split_whitespace();
match command_iter.next()
Some("add") => match process_add(&mut command_iter)
Ok((employee, department)) =>
let mut employees = departments.entry(department).or_insert(Vec::new());
employees.push(employee);
Err(err) => println!("Error: ", err),
,
Some("help") => help(),
Some("list") => println!(":#?", &departments),
Some("exit") => break,
Some(_) => println!(": Command unknown. Try `help`", command),
None => panic!("We shouldn't be here"),
fn help()
println!("help: show this help.");
println!("exit: exits this program.");
println!("show: shows the deparment structure.");
println!("add: adds an employee to a department");
println!(" - usage: `add <employee name> to <department_name>`");
fn print_promt()
print!("> ");
io::stdout().flush().ok().expect("Couldn't flush stdout!");
// I think this can be made better returning an Enum/Struct with a parsed command.
fn get_command() -> String
let mut command = String::new();
io::stdin()
.read_line(&mut command)
.expect("Couldn't read command!");
command
// The compiler told me to add the lifetime, but I don't understand why (I haven't reached that
// part of the book yet.)
// FIXME `SplitWhitespace` is too specific.
fn process_add<'a>(command: &mut SplitWhitespace) -> Result<(String, String), &'a str>
let mut employee = String::new();
let mut department = String::new();
// For a command "add Ronald Reagan to Old Presidents"
// - Consume the iterator onto `employee` until you find "to""
// - Consume the rest of the iterator onto `department`
// Using two loops feels naive though. I don't like the duplication inside them.
//
// Maybe `String` can be extended and I could add a `push_str_with_separator` method that does
// the extra check.
//
// employee.push_str_with_separator(word);
//
while let Some(word) = command.next()
if word == "to"
break;
if employee.len() > 0
employee.push_str(" ");
employee.push_str(word)
for word in command
if department.len() > 0
department.push_str(" ");
department.push_str(word);
if employee.len() > 0 && department.len() > 0
Ok((employee, department))
else
Err("Could not parse command. Try `add <employee name> to <department name>")
beginner rust
add a comment |Â
up vote
4
down vote
favorite
I'm learning Rust by learning the Rust programming language book. I'm now implementing the solution for the third challenge.
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 decided to do a simple UI to enter commands, but the implementation is very naive overall.
Rust is my first systems language. My background is in Ruby and Javascript.
use std::collections::HashMap;
use std::io::self, Write;
use std::str::SplitWhitespace;
fn main()
println!("Welcome to the department interface. Please run a command:");
help();
let mut departments: HashMap<String, Vec<String>> = HashMap::new();
loop
print_promt();
let command = get_command();
let mut command_iter = command.split_whitespace();
match command_iter.next()
Some("add") => match process_add(&mut command_iter)
Ok((employee, department)) =>
let mut employees = departments.entry(department).or_insert(Vec::new());
employees.push(employee);
Err(err) => println!("Error: ", err),
,
Some("help") => help(),
Some("list") => println!(":#?", &departments),
Some("exit") => break,
Some(_) => println!(": Command unknown. Try `help`", command),
None => panic!("We shouldn't be here"),
fn help()
println!("help: show this help.");
println!("exit: exits this program.");
println!("show: shows the deparment structure.");
println!("add: adds an employee to a department");
println!(" - usage: `add <employee name> to <department_name>`");
fn print_promt()
print!("> ");
io::stdout().flush().ok().expect("Couldn't flush stdout!");
// I think this can be made better returning an Enum/Struct with a parsed command.
fn get_command() -> String
let mut command = String::new();
io::stdin()
.read_line(&mut command)
.expect("Couldn't read command!");
command
// The compiler told me to add the lifetime, but I don't understand why (I haven't reached that
// part of the book yet.)
// FIXME `SplitWhitespace` is too specific.
fn process_add<'a>(command: &mut SplitWhitespace) -> Result<(String, String), &'a str>
let mut employee = String::new();
let mut department = String::new();
// For a command "add Ronald Reagan to Old Presidents"
// - Consume the iterator onto `employee` until you find "to""
// - Consume the rest of the iterator onto `department`
// Using two loops feels naive though. I don't like the duplication inside them.
//
// Maybe `String` can be extended and I could add a `push_str_with_separator` method that does
// the extra check.
//
// employee.push_str_with_separator(word);
//
while let Some(word) = command.next()
if word == "to"
break;
if employee.len() > 0
employee.push_str(" ");
employee.push_str(word)
for word in command
if department.len() > 0
department.push_str(" ");
department.push_str(word);
if employee.len() > 0 && department.len() > 0
Ok((employee, department))
else
Err("Could not parse command. Try `add <employee name> to <department name>")
beginner rust
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I'm learning Rust by learning the Rust programming language book. I'm now implementing the solution for the third challenge.
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 decided to do a simple UI to enter commands, but the implementation is very naive overall.
Rust is my first systems language. My background is in Ruby and Javascript.
use std::collections::HashMap;
use std::io::self, Write;
use std::str::SplitWhitespace;
fn main()
println!("Welcome to the department interface. Please run a command:");
help();
let mut departments: HashMap<String, Vec<String>> = HashMap::new();
loop
print_promt();
let command = get_command();
let mut command_iter = command.split_whitespace();
match command_iter.next()
Some("add") => match process_add(&mut command_iter)
Ok((employee, department)) =>
let mut employees = departments.entry(department).or_insert(Vec::new());
employees.push(employee);
Err(err) => println!("Error: ", err),
,
Some("help") => help(),
Some("list") => println!(":#?", &departments),
Some("exit") => break,
Some(_) => println!(": Command unknown. Try `help`", command),
None => panic!("We shouldn't be here"),
fn help()
println!("help: show this help.");
println!("exit: exits this program.");
println!("show: shows the deparment structure.");
println!("add: adds an employee to a department");
println!(" - usage: `add <employee name> to <department_name>`");
fn print_promt()
print!("> ");
io::stdout().flush().ok().expect("Couldn't flush stdout!");
// I think this can be made better returning an Enum/Struct with a parsed command.
fn get_command() -> String
let mut command = String::new();
io::stdin()
.read_line(&mut command)
.expect("Couldn't read command!");
command
// The compiler told me to add the lifetime, but I don't understand why (I haven't reached that
// part of the book yet.)
// FIXME `SplitWhitespace` is too specific.
fn process_add<'a>(command: &mut SplitWhitespace) -> Result<(String, String), &'a str>
let mut employee = String::new();
let mut department = String::new();
// For a command "add Ronald Reagan to Old Presidents"
// - Consume the iterator onto `employee` until you find "to""
// - Consume the rest of the iterator onto `department`
// Using two loops feels naive though. I don't like the duplication inside them.
//
// Maybe `String` can be extended and I could add a `push_str_with_separator` method that does
// the extra check.
//
// employee.push_str_with_separator(word);
//
while let Some(word) = command.next()
if word == "to"
break;
if employee.len() > 0
employee.push_str(" ");
employee.push_str(word)
for word in command
if department.len() > 0
department.push_str(" ");
department.push_str(word);
if employee.len() > 0 && department.len() > 0
Ok((employee, department))
else
Err("Could not parse command. Try `add <employee name> to <department name>")
beginner rust
I'm learning Rust by learning the Rust programming language book. I'm now implementing the solution for the third challenge.
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 decided to do a simple UI to enter commands, but the implementation is very naive overall.
Rust is my first systems language. My background is in Ruby and Javascript.
use std::collections::HashMap;
use std::io::self, Write;
use std::str::SplitWhitespace;
fn main()
println!("Welcome to the department interface. Please run a command:");
help();
let mut departments: HashMap<String, Vec<String>> = HashMap::new();
loop
print_promt();
let command = get_command();
let mut command_iter = command.split_whitespace();
match command_iter.next()
Some("add") => match process_add(&mut command_iter)
Ok((employee, department)) =>
let mut employees = departments.entry(department).or_insert(Vec::new());
employees.push(employee);
Err(err) => println!("Error: ", err),
,
Some("help") => help(),
Some("list") => println!(":#?", &departments),
Some("exit") => break,
Some(_) => println!(": Command unknown. Try `help`", command),
None => panic!("We shouldn't be here"),
fn help()
println!("help: show this help.");
println!("exit: exits this program.");
println!("show: shows the deparment structure.");
println!("add: adds an employee to a department");
println!(" - usage: `add <employee name> to <department_name>`");
fn print_promt()
print!("> ");
io::stdout().flush().ok().expect("Couldn't flush stdout!");
// I think this can be made better returning an Enum/Struct with a parsed command.
fn get_command() -> String
let mut command = String::new();
io::stdin()
.read_line(&mut command)
.expect("Couldn't read command!");
command
// The compiler told me to add the lifetime, but I don't understand why (I haven't reached that
// part of the book yet.)
// FIXME `SplitWhitespace` is too specific.
fn process_add<'a>(command: &mut SplitWhitespace) -> Result<(String, String), &'a str>
let mut employee = String::new();
let mut department = String::new();
// For a command "add Ronald Reagan to Old Presidents"
// - Consume the iterator onto `employee` until you find "to""
// - Consume the rest of the iterator onto `department`
// Using two loops feels naive though. I don't like the duplication inside them.
//
// Maybe `String` can be extended and I could add a `push_str_with_separator` method that does
// the extra check.
//
// employee.push_str_with_separator(word);
//
while let Some(word) = command.next()
if word == "to"
break;
if employee.len() > 0
employee.push_str(" ");
employee.push_str(word)
for word in command
if department.len() > 0
department.push_str(" ");
department.push_str(word);
if employee.len() > 0 && department.len() > 0
Ok((employee, department))
else
Err("Could not parse command. Try `add <employee name> to <department name>")
beginner rust
edited Jul 14 at 21:04
Jamalâ¦
30.1k11114225
30.1k11114225
asked Jul 14 at 20:57
afgomez
1211
1211
add a comment |Â
add a comment |Â
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f199513%2fhashmap-exercise-rust-book-ch-8%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password