1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
use crate::{hooks::Flag, Argv};
/// The CmdArgs struct that is passed to all command handlers.
#[derive(Debug, Clone)]
pub struct CmdArgs {
/// struct 'Argv' contains parsed flags and commands.
pub args: Argv,
/// Registered flags for the command by the struct 'Command::flag'.
pub registered_flags: Vec<(String, Flag)>,
}
pub type Handler = fn(args: CmdArgs) -> i32;
/// The Command struct to initialize a new command.
/// ## Non-complete example:
/// ```rust
/// use clier::command::Command;
/// use clier::hooks::Flag;
///
/// let command = Command::new(
/// /* command name: */ "command",
/// /* description: */ "description",
/// /* handler: */ |_args| {
/// /* Your logic */
/// 0 // <-- i32: Exit Code of program, success = 0
/// })
/// .usage("command [usage text]")
/// .flags(vec![
/// Flag::new("flag-name", "flag description".to_string() /* <-- In help */)
/// .short('t')
/// ]);
/// ```
/// Alot of these properties/builder methods are no necesserialy required, but are usefull for the user in the help output.
/// ## Subcommand
/// It is also possible to add subcommands to a command:
/// ```rust
/// use clier::command::Command;
/// use clier::hooks::Flag;
///
/// let command = Command::new(
/// /* command name: */ "command",
/// /* description: */ "description",
/// /* handler: */ |_args| {
/// /* Your logic */
/// 0 // <-- i32: Exit Code of program, success = 0
/// })
/// .usage("command [usage text]")
/// .flags(vec![
/// Flag::new("flag-name", "flag description".to_string() /* <-- In help */)
/// .short('t')
/// ]);
///
/// command.subcommand(
/// "subcommand",
/// "description",
/// Some("usage"),
/// |_args| {
/// /* Your logic */
/// 0 // <-- i32: Exit Code of program, success = 0
/// });
/// ```
///
/// It has almost the same methods and builder methods as a [Command][crate::command::Command]
#[derive(Debug, Clone)]
pub struct Command {
pub(crate) name: String,
pub(crate) handler: Handler,
pub(crate) usage: Option<String>,
pub(crate) flags: Option<Vec<Flag>>,
pub(crate) description: String,
pub(crate) children: Option<Vec<Command>>,
}
impl Command {
pub fn new(name: &str, description: &str, handler: Handler) -> Self {
Self {
name: name.to_string(),
description: description.to_string(),
flags: None,
usage: None,
handler,
children: None,
}
}
pub fn usage(mut self, usage: &str) -> Self {
self.usage = Some(usage.to_string());
self
}
pub fn flags(mut self, flags: Vec<Flag>) -> Self {
self.flags = Some(flags);
self
}
pub fn subcommand(
mut self,
name: &str,
description: &str,
usage: Option<&str>,
handler: Handler,
) -> Self {
let mut new_command = Self::new(name, description, handler);
if let Some(usage) = usage {
new_command = new_command.clone().usage(usage);
}
self.children.as_mut().unwrap_or(&mut vec![]).push(new_command);
self
}
}