Reads a line of text interactively from the console, which is not expected to be a TTY.
(console: &mut dyn Console)
| 446 | |
| 447 | /// Reads a line of text interactively from the console, which is not expected to be a TTY. |
| 448 | async fn read_line_raw(console: &mut dyn Console) -> io::Result<String> { |
| 449 | let mut line = String::new(); |
| 450 | loop { |
| 451 | match console.read_key().await? { |
| 452 | Key::ArrowUp | Key::ArrowDown | Key::ArrowLeft | Key::ArrowRight => (), |
| 453 | Key::Backspace => { |
| 454 | if !line.is_empty() { |
| 455 | line.pop(); |
| 456 | } |
| 457 | } |
| 458 | Key::CarriageReturn => { |
| 459 | // TODO(jmmv): This is here because the integration tests may be checked out with |
| 460 | // CRLF line endings on Windows, which means we'd see two characters to end a line |
| 461 | // instead of one. Not sure if we should do this or if instead we should ensure |
| 462 | // the golden data we feed to the tests has single-character line endings. |
| 463 | if cfg!(not(target_os = "windows")) { |
| 464 | break; |
| 465 | } |
| 466 | } |
| 467 | Key::Char(ch) => line.push(ch), |
| 468 | Key::Delete => (), |
| 469 | Key::End | Key::Home => (), |
| 470 | Key::Escape => (), |
| 471 | Key::EofOrDelete => return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "EOF")), |
| 472 | Key::Interrupt => return Err(io::Error::new(io::ErrorKind::Interrupted, "Ctrl+C")), |
| 473 | Key::NewLine => break, |
| 474 | Key::PageDown | Key::PageUp => (), |
| 475 | Key::Tab => (), |
| 476 | Key::Unknown => line.push('?'), |
| 477 | } |
| 478 | } |
| 479 | Ok(line) |
| 480 | } |
| 481 | |
| 482 | /// Reads a line from the console. If the console is interactive, this does fancy line editing and |
| 483 | /// uses the given `prompt` and pre-fills the input with `previous`. |