summaryrefslogtreecommitdiffstats
path: root/third_party/rust/clap/examples/repl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/clap/examples/repl.rs')
-rw-r--r--third_party/rust/clap/examples/repl.rs94
1 files changed, 94 insertions, 0 deletions
diff --git a/third_party/rust/clap/examples/repl.rs b/third_party/rust/clap/examples/repl.rs
new file mode 100644
index 0000000000..f1b65c3090
--- /dev/null
+++ b/third_party/rust/clap/examples/repl.rs
@@ -0,0 +1,94 @@
+// Note: this requires the `unstable-multicall` feature
+
+use std::io::Write;
+
+use clap::Command;
+
+fn main() -> Result<(), String> {
+ loop {
+ let line = readline()?;
+ let line = line.trim();
+ if line.is_empty() {
+ continue;
+ }
+
+ match respond(line) {
+ Ok(quit) => {
+ if quit {
+ break;
+ }
+ }
+ Err(err) => {
+ write!(std::io::stdout(), "{}", err).map_err(|e| e.to_string())?;
+ std::io::stdout().flush().map_err(|e| e.to_string())?;
+ }
+ }
+ }
+
+ Ok(())
+}
+
+fn respond(line: &str) -> Result<bool, String> {
+ let args = shlex::split(line).ok_or("error: Invalid quoting")?;
+ let matches = cli()
+ .try_get_matches_from(&args)
+ .map_err(|e| e.to_string())?;
+ match matches.subcommand() {
+ Some(("ping", _matches)) => {
+ write!(std::io::stdout(), "Pong").map_err(|e| e.to_string())?;
+ std::io::stdout().flush().map_err(|e| e.to_string())?;
+ }
+ Some(("quit", _matches)) => {
+ write!(std::io::stdout(), "Exiting ...").map_err(|e| e.to_string())?;
+ std::io::stdout().flush().map_err(|e| e.to_string())?;
+ return Ok(true);
+ }
+ Some((name, _matches)) => unimplemented!("{}", name),
+ None => unreachable!("subcommand required"),
+ }
+
+ Ok(false)
+}
+
+fn cli() -> Command<'static> {
+ // strip out usage
+ const PARSER_TEMPLATE: &str = "\
+ {all-args}
+ ";
+ // strip out name/version
+ const APPLET_TEMPLATE: &str = "\
+ {about-with-newline}\n\
+ {usage-heading}\n {usage}\n\
+ \n\
+ {all-args}{after-help}\
+ ";
+
+ Command::new("repl")
+ .multicall(true)
+ .arg_required_else_help(true)
+ .subcommand_required(true)
+ .subcommand_value_name("APPLET")
+ .subcommand_help_heading("APPLETS")
+ .help_template(PARSER_TEMPLATE)
+ .subcommand(
+ Command::new("ping")
+ .about("Get a response")
+ .help_template(APPLET_TEMPLATE),
+ )
+ .subcommand(
+ Command::new("quit")
+ .alias("exit")
+ .about("Quit the REPL")
+ .help_template(APPLET_TEMPLATE),
+ )
+}
+
+fn readline() -> Result<String, String> {
+ write!(std::io::stdout(), "$ ").map_err(|e| e.to_string())?;
+ std::io::stdout().flush().map_err(|e| e.to_string())?;
+ let mut buffer = String::new();
+ std::io::stdin()
+ .read_line(&mut buffer)
+ .map_err(|e| e.to_string())?;
+ Ok(buffer)
+}