Castle
Castle

Reputation: 7

why my Rust program always enters while loop and never exits

I am reading through the Rust book and doing the optinal exercise along the way. I've finished the chapter 8 (Common Collections) and am trying the last exercise. The exercise instructions are:

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.

What I want my program to do is firstly ask the user if they want to add a new employee, if no, the program ends else it allows them to continously add an employee until the user declines to add any more.

I've chosen to simply start with the initial user prompt asking if they want to add a new employee. I start with an empty String for the user input, once the user enters their response there is a while loop that repeats until the user enters a valid response ([Y/n]). Since the condition for the while loop is when the response is not equal to "y" or "n" I expected correct responses to skip the while loop but instead the while loop is always entered and never exited no matter what. Since I'm new to Rust I'm not sure if there some obvious or idiosyncratic reason for this behaviour. I'll also add that I remove whitespace (incl. \n) from the response and make the response lowercase in the while loop condition, all of which can be seen in my code below.

use std::collections::{HashMap, HashSet};
use std::io;

const DEPARTMENT: [&str; 5] = ["Engineering", "IT", "Sales", "Marketing", "HR"];

fn main() {
    // Initialize company roster
    let mut company: HashMap<String, HashSet<String>> = HashMap::new();
    for key in DEPARTMENT.iter() {
        company.insert((*key).to_string(), HashSet::new());
    }
    // println!("{:?}", company);

    let mut response = String::new();

    // Prompt user to add a new employee or not
    print!("Would you like to add an employee to the company roster? [Y/n] ");
    io::stdin().read_line(&mut response).expect("Failed to read line.");
    remove_whitespace(&mut response);

    // Ensure response is valid
    while response.to_lowercase() != "y" || response.to_lowercase() != "n" {
        response.drain(..);
        println!();
        print!("Please respond to the previous question with either 'y' or 'n' (case insensitive): ");
        io::stdin().read_line(&mut response).expect("Failed to read line.");
        remove_whitespace(&mut response);
        // print!("\n{}", response.to_lowercase() == "y" || response.to_lowercase() == "n");
    }
}

fn remove_whitespace(s: &mut String) {
    s.retain(|c| !c.is_whitespace());
}

I'd appreciate any assistance to help me understand why the program doesn't do what I expect.

Upvotes: 0

Views: 274

Answers (1)

Check your while conditions (it is always true) , and what you wrote

"loop is when the response is not equal to "y" or "n""

means in pseudo code

NOT (answer = "y" OR answer="n")

Upvotes: 2

Related Questions