screen.rs (1898B)
1 use std::io::{stdin, stdout, Write}; 2 3 pub fn clear() { 4 println!("\x1B[H\x1B[2J"); 5 } 6 7 fn prompt(prompt: &str) -> String { 8 let mut message: Option<&str> = None; 9 loop { 10 if message.is_some() { 11 println!("Error: {}", message.unwrap()); 12 } 13 print!("{}", prompt); 14 let _ = stdout().flush(); 15 16 let mut input_text = String::new(); 17 if stdin().read_line(&mut input_text).is_err() { 18 message = Some("did not input text."); 19 continue; 20 } 21 return input_text.trim().to_string(); 22 } 23 } 24 25 pub fn list_menu(list: &[String]) -> Option<(usize, String)> { 26 let mut message = None; 27 loop { 28 clear(); 29 println!("== Internet Radio Player =="); 30 for (i, val) in list.iter().enumerate() { 31 println!("{} {}", i + 1, val); 32 } 33 println!("Type 'q' or 'quit' to go back, press ^C to exit."); 34 if message.is_some() { 35 println!("Error: {}", message.unwrap()); 36 } 37 38 // can't use just prompt(..), because match goes on &str, and prompt returns String. 39 // can't use prompt(..).as_str(), because temporary value dropped while borrowed. 40 // - i could use a new variable here, but it's clutter. 41 // So, I reborrow with &*. 42 let trimmed = &*prompt("Enter number> "); 43 44 let n = match trimmed.parse::<usize>() { 45 Ok(n) => n, 46 _ => match trimmed { 47 "q" | "quit" => { 48 return None; 49 } 50 _ => { 51 message = Some("Not a number!"); 52 continue; 53 } 54 }, 55 }; 56 if n == 0 || n > list.len() { 57 message = Some("choice out of range"); 58 continue; 59 } 60 let index = n - 1; 61 62 return Some((index, list[index].to_string())); 63 } 64 }