119625d8cSopenharmony_ciuse std::io::Write; 219625d8cSopenharmony_ci 319625d8cSopenharmony_ciuse clap::Command; 419625d8cSopenharmony_ci 519625d8cSopenharmony_cifn main() -> Result<(), String> { 619625d8cSopenharmony_ci loop { 719625d8cSopenharmony_ci let line = readline()?; 819625d8cSopenharmony_ci let line = line.trim(); 919625d8cSopenharmony_ci if line.is_empty() { 1019625d8cSopenharmony_ci continue; 1119625d8cSopenharmony_ci } 1219625d8cSopenharmony_ci 1319625d8cSopenharmony_ci match respond(line) { 1419625d8cSopenharmony_ci Ok(quit) => { 1519625d8cSopenharmony_ci if quit { 1619625d8cSopenharmony_ci break; 1719625d8cSopenharmony_ci } 1819625d8cSopenharmony_ci } 1919625d8cSopenharmony_ci Err(err) => { 2019625d8cSopenharmony_ci write!(std::io::stdout(), "{err}").map_err(|e| e.to_string())?; 2119625d8cSopenharmony_ci std::io::stdout().flush().map_err(|e| e.to_string())?; 2219625d8cSopenharmony_ci } 2319625d8cSopenharmony_ci } 2419625d8cSopenharmony_ci } 2519625d8cSopenharmony_ci 2619625d8cSopenharmony_ci Ok(()) 2719625d8cSopenharmony_ci} 2819625d8cSopenharmony_ci 2919625d8cSopenharmony_cifn respond(line: &str) -> Result<bool, String> { 3019625d8cSopenharmony_ci let args = shlex::split(line).ok_or("error: Invalid quoting")?; 3119625d8cSopenharmony_ci let matches = cli() 3219625d8cSopenharmony_ci .try_get_matches_from(args) 3319625d8cSopenharmony_ci .map_err(|e| e.to_string())?; 3419625d8cSopenharmony_ci match matches.subcommand() { 3519625d8cSopenharmony_ci Some(("ping", _matches)) => { 3619625d8cSopenharmony_ci write!(std::io::stdout(), "Pong").map_err(|e| e.to_string())?; 3719625d8cSopenharmony_ci std::io::stdout().flush().map_err(|e| e.to_string())?; 3819625d8cSopenharmony_ci } 3919625d8cSopenharmony_ci Some(("quit", _matches)) => { 4019625d8cSopenharmony_ci write!(std::io::stdout(), "Exiting ...").map_err(|e| e.to_string())?; 4119625d8cSopenharmony_ci std::io::stdout().flush().map_err(|e| e.to_string())?; 4219625d8cSopenharmony_ci return Ok(true); 4319625d8cSopenharmony_ci } 4419625d8cSopenharmony_ci Some((name, _matches)) => unimplemented!("{}", name), 4519625d8cSopenharmony_ci None => unreachable!("subcommand required"), 4619625d8cSopenharmony_ci } 4719625d8cSopenharmony_ci 4819625d8cSopenharmony_ci Ok(false) 4919625d8cSopenharmony_ci} 5019625d8cSopenharmony_ci 5119625d8cSopenharmony_cifn cli() -> Command { 5219625d8cSopenharmony_ci // strip out usage 5319625d8cSopenharmony_ci const PARSER_TEMPLATE: &str = "\ 5419625d8cSopenharmony_ci {all-args} 5519625d8cSopenharmony_ci "; 5619625d8cSopenharmony_ci // strip out name/version 5719625d8cSopenharmony_ci const APPLET_TEMPLATE: &str = "\ 5819625d8cSopenharmony_ci {about-with-newline}\n\ 5919625d8cSopenharmony_ci {usage-heading}\n {usage}\n\ 6019625d8cSopenharmony_ci \n\ 6119625d8cSopenharmony_ci {all-args}{after-help}\ 6219625d8cSopenharmony_ci "; 6319625d8cSopenharmony_ci 6419625d8cSopenharmony_ci Command::new("repl") 6519625d8cSopenharmony_ci .multicall(true) 6619625d8cSopenharmony_ci .arg_required_else_help(true) 6719625d8cSopenharmony_ci .subcommand_required(true) 6819625d8cSopenharmony_ci .subcommand_value_name("APPLET") 6919625d8cSopenharmony_ci .subcommand_help_heading("APPLETS") 7019625d8cSopenharmony_ci .help_template(PARSER_TEMPLATE) 7119625d8cSopenharmony_ci .subcommand( 7219625d8cSopenharmony_ci Command::new("ping") 7319625d8cSopenharmony_ci .about("Get a response") 7419625d8cSopenharmony_ci .help_template(APPLET_TEMPLATE), 7519625d8cSopenharmony_ci ) 7619625d8cSopenharmony_ci .subcommand( 7719625d8cSopenharmony_ci Command::new("quit") 7819625d8cSopenharmony_ci .alias("exit") 7919625d8cSopenharmony_ci .about("Quit the REPL") 8019625d8cSopenharmony_ci .help_template(APPLET_TEMPLATE), 8119625d8cSopenharmony_ci ) 8219625d8cSopenharmony_ci} 8319625d8cSopenharmony_ci 8419625d8cSopenharmony_cifn readline() -> Result<String, String> { 8519625d8cSopenharmony_ci write!(std::io::stdout(), "$ ").map_err(|e| e.to_string())?; 8619625d8cSopenharmony_ci std::io::stdout().flush().map_err(|e| e.to_string())?; 8719625d8cSopenharmony_ci let mut buffer = String::new(); 8819625d8cSopenharmony_ci std::io::stdin() 8919625d8cSopenharmony_ci .read_line(&mut buffer) 9019625d8cSopenharmony_ci .map_err(|e| e.to_string())?; 9119625d8cSopenharmony_ci Ok(buffer) 9219625d8cSopenharmony_ci} 93