Crate clap_reverse

Crate clap_reverse 

Source
Expand description

ClapReverse is a Rust procedural macro library designed to simplify the construction of std::process::Command from a Rust struct. It allows you to define commands declaratively, with struct fields representing arguments, options, and flags, while providing control over formatting, prefixes, and delimiters. This approach reduces boilerplate code when calling external commands.

§Core Concepts

The library revolves around the AsCommand trait:

pub trait AsCommand {
    fn as_command(&self) -> std::process::Command;
}

Implementing this trait allows converting any annotated struct into a fully constructed std::process::Command that can be spawned or executed.

§Struct Attributes

Struct-level attributes define defaults and global behaviors for the command:

AttributeDescription
displayGenerates an implementation of std::fmt::Display, which prints the equivalent command line string.
prefixSets a default prefix for all arguments (default "--"). Example: prefix="-" produces -arg value.
delimiterSets a delimiter between argument names and values (default " "). Example: delimiter="=" produces --arg=value.
binarySpecifies a static binary for the command. Example: binary="echo" will always run the echo command.

§Field Attributes

Field-level attributes customize the behavior of individual fields in the command:

AttributeDescription
prefixOverrides the struct-level prefix for this field. Example: prefix="-" produces -arg value.
nameOverrides the field name in the command. If not set, the Rust field name is used.
delimiterOverrides the struct-level delimiter for this field. Example: delimiter="=" produces --arg=value.
binaryMarks a field as the binary source for the command. Only one field can have this.
transparentOmits the argument name and prints only the value.
flagMarks a boolean field as a flag that is included in the command only if true. Cannot be applied to non-boolean fields.

Note: All fields except those marked as flag must implement std::fmt::Display.

§Command Construction Rules

These rules govern how the macro generates a std::process::Command from a struct and its annotated fields.

  1. Only boolean fields may use the flag attribute. Flags appear in the command only if true.
  2. The binary attribute may appear either as a struct-level string or on a single field. Struct-level binary uses a fixed command name, while field-level binary derives the command from the field’s value.
  3. Fields of type Option<T> are appended only if Some(value); otherwise they are skipped.
  4. Argument formatting generally follows {prefix}{name}{delimiter}{value}. Exceptions:
    • transparent fields omit {prefix}{name}{delimiter} and print only the value.
    • flag fields omit {delimiter}{value} entirely.
  5. Prefixes and delimiters can be overridden on a per-field basis; field-level attributes take precedence over struct-level defaults.
  6. If the name attribute is not provided, the Rust field name is used as the argument name.

§Example Usage

use clap_reverse::{ClapReverse, AsCommand};

#[derive(Debug, ClapReverse)]
#[clap_reverse(display, binary = "echo", prefix="--", delimiter="=")]
struct Echo {
    #[clap_reverse(transparent)]
    text: String,
    #[clap_reverse(flag)]
    loud: bool,
    #[clap_reverse(name="count")]
    times: Option<u32>,
}

let echo = Echo {
   text: "Hello, World!".to_string(),
   loud: true,
   times: Some(3),
};

println!("Echo structure: {echo:#?}");

// Display representation (command string)
println!("Echo command: `{echo}`");  // echo Hello, World! --loud --count=3

// Execute the command
let _exit_status = echo.as_command()
   .spawn()
   .expect("Failed to spawn `echo` command")
   .wait()
   .expect("Failed to wait on `echo` command");

Traits§

AsCommand
Converts a Rust struct into a std::process::Command.

Derive Macros§

ClapReverse
Derive macro to automatically implement [AsCommand] for a struct, allowing it to be converted into a [std::process::Command]. If display is specified in struct attributes, it also implements [std::fmt::Display] to show the equivalent command line.