diff --git a/Cargo.toml b/Cargo.toml index 7192e79e369..1ee2d968c2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,6 +159,11 @@ name = "repl" path = "examples/repl.rs" required-features = ["help"] +[[example]] +name = "repl-derive" +path = "examples/repl-derive.rs" +required-features = ["derive"] + [[example]] name = "01_quick" path = "examples/tutorial_builder/01_quick.rs" diff --git a/examples/repl-derive.rs b/examples/repl-derive.rs new file mode 100644 index 00000000000..8de9b33e4ed --- /dev/null +++ b/examples/repl-derive.rs @@ -0,0 +1,67 @@ +use std::io::Write; + +use clap::{Parser, Subcommand}; + +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 { + let args = shlex::split(line).ok_or("error: Invalid quoting")?; + let cli = Cli::try_parse_from(args).map_err(|e| e.to_string())?; + match cli.command { + Commands::Ping => { + write!(std::io::stdout(), "Pong").map_err(|e| e.to_string())?; + std::io::stdout().flush().map_err(|e| e.to_string())?; + } + Commands::Exit => { + write!(std::io::stdout(), "Exiting ...").map_err(|e| e.to_string())?; + std::io::stdout().flush().map_err(|e| e.to_string())?; + return Ok(true); + } + } + Ok(false) +} + +#[derive(Debug, Parser)] +#[command(multicall = true)] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Debug, Subcommand)] +enum Commands { + Ping, + Exit, +} + +fn readline() -> Result { + 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) +} diff --git a/src/_cookbook/mod.rs b/src/_cookbook/mod.rs index dacb1219a88..9753d37a059 100644 --- a/src/_cookbook/mod.rs +++ b/src/_cookbook/mod.rs @@ -43,7 +43,7 @@ //! - Topics: //! - Subcommands //! -//! repl: [builder][repl] +//! repl: [builder][repl], [derive][repl_derive] //! - Topics: //! - Read-Eval-Print Loops / Custom command lines @@ -58,4 +58,5 @@ pub mod multicall_busybox; pub mod multicall_hostname; pub mod pacman; pub mod repl; +pub mod repl_derive; pub mod typed_derive; diff --git a/src/_cookbook/repl_derive.rs b/src/_cookbook/repl_derive.rs new file mode 100644 index 00000000000..3cadf2652e1 --- /dev/null +++ b/src/_cookbook/repl_derive.rs @@ -0,0 +1,4 @@ +//! # Example: REPL (Derive API) +//! +//! ```rust +#![doc = include_str!("../../examples/repl-derive.rs")]