From a6391ae9e3870fec66abe1c95b89b7a80a4d035e Mon Sep 17 00:00:00 2001 From: Eric R Date: Tue, 23 Jan 2024 17:35:15 -0500 Subject: [PATCH] docs(example): Added repl derive example --- Cargo.toml | 5 +++ examples/repl-derive.md | 41 +++++++++++++++++++ examples/repl-derive.rs | 79 ++++++++++++++++++++++++++++++++++++ src/_cookbook/mod.rs | 3 +- src/_cookbook/repl_derive.rs | 7 ++++ 5 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 examples/repl-derive.md create mode 100644 examples/repl-derive.rs create mode 100644 src/_cookbook/repl_derive.rs diff --git a/Cargo.toml b/Cargo.toml index 7192e79e..1ee2d968 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.md b/examples/repl-derive.md new file mode 100644 index 00000000..79c56651 --- /dev/null +++ b/examples/repl-derive.md @@ -0,0 +1,41 @@ +**This requires enabling the [`derive` feature flag][crate::_features].** + +Help: +```console +$ echo --help +Usage: echo --text + +Options: + -h, --help Print help + +Echo: + -t, --text The text to be echoed [aliases: text] +$ ping --help +Usage: ping + +Options: + -h, --help Print help +$ exit --help +Usage: exit + +Options: + -h, --help Print help +``` + +Echo: +```console +$ echo -t 'Hello, world!' +Hello, world! +``` + +Ping: +```console +$ ping +pong +``` + +Exit: +```console +$ exit +Exiting ... +``` \ No newline at end of file diff --git a/examples/repl-derive.rs b/examples/repl-derive.rs new file mode 100644 index 00000000..6a1029a8 --- /dev/null +++ b/examples/repl-derive.rs @@ -0,0 +1,79 @@ +use std::io::Write; + +use clap::{Args, Parser, Subcommand}; + +#[derive(Debug, Parser)] +#[command(multicall = true)] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Debug, Subcommand)] +enum Commands { + Echo(EchoArgs), + Ping, + Exit, +} + +#[derive(Args, Debug)] +pub struct EchoArgs { + #[arg( + short = 't', + long = "text", + visible_alias = "text", + help = "The text to be echoed", + help_heading = "Echo", + )] + text: String, +} + +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::Echo(args) => { + println!("{}", args.text); + } + Commands::Ping => { + println!("Pong"); + } + Commands::Exit => { + println!("Exiting ..."); + return Ok(true); + } + } + Ok(false) +} + +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) +} + +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(()) +} diff --git a/src/_cookbook/mod.rs b/src/_cookbook/mod.rs index dacb1219..9753d37a 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 00000000..e7c98022 --- /dev/null +++ b/src/_cookbook/repl_derive.rs @@ -0,0 +1,7 @@ +//! # Example: REPL (Derive API) +//! +//! ```rust +#![doc = include_str!("../../examples/repl-derive.rs")] +//! ``` +//! +#![doc = include_str!("../../examples/repl-derive.md")]