0

I want to create a login screen in CLI and I want to make the password prompt to detect keypresses and add the characters to a variable but not to display anything (or display asterisks instead).

I'm using the crate crossterm = "0.23.2" and this is my code:

#[macro_use]
extern crate crossterm;

use std::io::{self, Write};

use crossterm::cursor;
use crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
use crossterm::terminal::{Clear, ClearType};

fn main() {
  let mut stdout = io::stdout();

  execute!(stdout, Clear(ClearType::All), cursor::MoveTo(0, 0))
    .unwrap();

  println!("********** LOGIN **********\n");

  let mut username = String::new();
  let mut password = String::new();
    
  print!("username: ");
  stdout.flush()
    .unwrap();

  io::stdin()
    .read_line(&mut username)
    .expect("Failed to read username");

  username = username.trim().to_string();

  print!("password: ");
  stdout.flush()
    .unwrap();

  loop {
    match read().unwrap() {
      Event::Key(KeyEvent {
        code: KeyCode::Enter,
        modifiers: KeyModifiers::NONE,
      }) => break,
      Event::Key(KeyEvent {
        code: KeyCode::Char(c),
        modifiers: KeyModifiers::NONE,
      }) => {
        password.push(c);
      },
      _ => {},
    }
  }
}

but this still shows the characters I type into the password prompt. Is there a way to stop them from showing? (e.g. overwriting the default keypress event handler in some way, just an idea)

kometen
  • 5,148
  • 4
  • 40
  • 44

0 Answers0