summaryrefslogtreecommitdiffstats
path: root/src/bin/client/repl.rs
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-03-02 17:56:49 +0100
committersalmonik <raisersoft@proton.me>2026-03-02 17:56:49 +0100
commiteb0e61b1aef2fd0fddabcaec6ea318773b65717e (patch)
tree7bb7aec64570f52fb010e1f4248a6ff82181b812 /src/bin/client/repl.rs
parentslowly preparing for actual casino (diff)
downloadzagan-bet-eb0e61b1aef2fd0fddabcaec6ea318773b65717e.tar.gz
zagan-bet-eb0e61b1aef2fd0fddabcaec6ea318773b65717e.zip
only use raw mode
Diffstat (limited to 'src/bin/client/repl.rs')
-rw-r--r--src/bin/client/repl.rs83
1 files changed, 74 insertions, 9 deletions
diff --git a/src/bin/client/repl.rs b/src/bin/client/repl.rs
index b2f6ecd..4e787cb 100644
--- a/src/bin/client/repl.rs
+++ b/src/bin/client/repl.rs
@@ -6,7 +6,7 @@ use std::time::Instant;
6use crate::connection; 6use crate::connection;
7use crate::database; 7use crate::database;
8 8
9use crossterm::{event::{read, Event, KeyCode, KeyModifiers}, terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType}, cursor::{MoveToColumn, Show}, execute}; 9use crossterm::{event::{read, Event, KeyCode, KeyModifiers}, terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType}, cursor::{MoveToColumn, Show, Hide}, execute};
10 10
11use sha2::{Sha256, Digest}; 11use sha2::{Sha256, Digest};
12 12
@@ -172,7 +172,7 @@ impl ClientState {
172 if username.is_empty() { 172 if username.is_empty() {
173 continue 'outer; 173 continue 'outer;
174 } 174 }
175 let password = read_line("Password: "); 175 let password = read_password("Password: ");
176 if password.is_empty() { 176 if password.is_empty() {
177 continue 'outer; 177 continue 'outer;
178 } 178 }
@@ -217,7 +217,7 @@ impl ClientState {
217 if username.is_empty() { 217 if username.is_empty() {
218 break; 218 break;
219 } 219 }
220 let password = read_line("Password: "); 220 let password = read_password("Password: ");
221 if password.is_empty() { 221 if password.is_empty() {
222 break; 222 break;
223 } 223 }
@@ -268,7 +268,7 @@ impl ClientState {
268 if username.is_empty() { 268 if username.is_empty() {
269 continue 'outer; 269 continue 'outer;
270 } 270 }
271 let password = read_line("Password: "); 271 let password = read_password("Password: ");
272 if password.is_empty() { 272 if password.is_empty() {
273 continue 'outer; 273 continue 'outer;
274 } 274 }
@@ -367,14 +367,13 @@ impl ClientState {
367 *current_input = matches[0].clone(); 367 *current_input = matches[0].clone();
368 redraw(current_input); 368 redraw(current_input);
369 } else if matches.len() > 1 { 369 } else if matches.len() > 1 {
370 disable_raw_mode().unwrap();
371 execute!(stdout(), Show).unwrap(); 370 execute!(stdout(), Show).unwrap();
372 println!("\nPossible completions:"); 371 println!("\nPossible completions:");
373 for m in &matches { 372 for m in &matches {
374 print!("{} ", m); 373 print!("{} ", m);
375 } 374 }
376 println!(); 375 println!();
377 enable_raw_mode().unwrap(); 376 execute!(stdout(), Hide).unwrap();
378 redraw(current_input); 377 redraw(current_input);
379 } 378 }
380 // else do nothing 379 // else do nothing
@@ -420,12 +419,78 @@ fn redraw(current_input: &str) {
420} 419}
421 420
422fn read_line(prompt: &str) -> String { 421fn read_line(prompt: &str) -> String {
423 disable_raw_mode().unwrap();
424 execute!(stdout(), Show).unwrap(); 422 execute!(stdout(), Show).unwrap();
425 print!("{}", prompt); 423 print!("{}", prompt);
426 stdout().flush().unwrap(); 424 stdout().flush().unwrap();
425
427 let mut input = String::new(); 426 let mut input = String::new();
428 std::io::stdin().read_line(&mut input).unwrap(); 427 let prompt_len = prompt.len();
429 enable_raw_mode().unwrap(); 428
429 loop {
430 match read().unwrap() {
431 Event::Key(key) => match key.code {
432 KeyCode::Enter => {
433 println!();
434 break;
435 }
436 KeyCode::Backspace => {
437 if !input.is_empty() {
438 input.pop();
439 // Move cursor back and clear from current position to end of line
440 execute!(stdout(), MoveToColumn((prompt_len + input.len() + 1) as u16),
441 Clear(ClearType::UntilNewLine)).unwrap();
442 stdout().flush().unwrap();
443 }
444 }
445 KeyCode::Char(c) => {
446 input.push(c);
447 print!("{}", c);
448 stdout().flush().unwrap();
449 }
450 _ => {}
451 },
452 _ => {}
453 }
454 }
455 input.trim().to_string()
456}
457
458fn read_password(prompt: &str) -> String {
459 execute!(stdout(), Show).unwrap();
460 print!("{}", prompt);
461 stdout().flush().unwrap();
462
463 let mut input = String::new();
464 let mut display = String::new();
465 let prompt_len = prompt.len();
466
467 loop {
468 match read().unwrap() {
469 Event::Key(key) => match key.code {
470 KeyCode::Enter => {
471 println!();
472 break;
473 }
474 KeyCode::Backspace => {
475 if !input.is_empty() {
476 input.pop();
477 display.pop();
478 // Move cursor back and clear from current position to end of line
479 execute!(stdout(), MoveToColumn((prompt_len + display.len() + 1) as u16),
480 Clear(ClearType::UntilNewLine)).unwrap();
481 stdout().flush().unwrap();
482 }
483 }
484 KeyCode::Char(c) => {
485 input.push(c);
486 display.push('*');
487 print!("*");
488 stdout().flush().unwrap();
489 }
490 _ => {}
491 },
492 _ => {}
493 }
494 }
430 input.trim().to_string() 495 input.trim().to_string()
431} 496}