3 stable releases

new 1.2.0 Jan 14, 2025
1.1.0 Jan 11, 2025
1.0.0 Jan 11, 2025

#230 in Procedural macros

Download history 179/week @ 2025-01-05 526/week @ 2025-01-12

705 downloads per month

MIT license

27KB
518 lines

comlexr

comlexr is a Rust procedural macro crate designed to simplify command expression generation by using flexible syntax constructs. It allows you to dynamically build command-line instructions based on conditional statements, loops, pattern matching, closures, and more.

Installation

Add comlexr to your project's Cargo.toml:

[dependencies]
comlexr = "1.2.0"

Rust Edition

This project uses Rust 2018 edition to ensure compatibility and stable language features.

Usage

Basic Command Construction

Create simple command expressions using the cmd! macro.

use comlexr::cmd;

let command = cmd!("echo", "test");
assert_eq!(format!("{command:?}"), r#""echo" "test""#.to_string());

Conditional Argument Inclusion

Use if statements to conditionally include arguments.

use comlexr::cmd;

let single = true;
let multi = false;

let command = cmd!(
    "echo",
    "test",
    if single => "single",
    if multi => [
        "multi",
        "arg",
    ],
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "single""#.to_string());

Conditional Pattern Matching

Use if let syntax to conditionally include arguments based on pattern matching.

use comlexr::cmd;

let single_option = Some("single");
let multi_option: Option<&str> = None;

let command = cmd!(
    "echo",
    "test",
    if let Some(arg) = single_option => arg,
    if let Some(arg) = multi_option => [
        "multi",
        arg,
    ],
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "single""#.to_string());

Iterative Argument Inclusion

Use the for syntax to iterate over collections and include multiple arguments.

use comlexr::cmd;

let iter = &["1", "2"];
let command = cmd!(
    "echo",
    "test",
    for iter,
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "1" "2""#.to_string());

Iteration with for in

Leverage the for in syntax to map collection elements to arguments dynamically.

use comlexr::cmd;

let single_iter = &["arg1", "arg2"];
let multi_iter = &["multi1", "multi2"];

let command = cmd!(
    "echo",
    "test",
    for arg in single_iter => arg,
    for arg in multi_iter => [
        "multi",
        arg,
    ],
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "arg1" "arg2" "multi" "multi1" "multi" "multi2""#.to_string());

Pattern Matching with match

Dynamically choose arguments based on pattern matching.

use comlexr::cmd;

enum TestArgs {
    Arg1,
    Arg2,
    Arg3,
}

let match_arg = TestArgs::Arg2;
let command = cmd!(
    "echo",
    "test",
    match match_arg {
        TestArgs::Arg1 => "arg1",
        TestArgs::Arg2 => ["arg1", "arg2"],
        TestArgs::Arg3 => ["arg1", "arg2", "arg3"],
    }
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "arg1" "arg2""#.to_string());

Closures for Dynamic Argument Generation

Generate arguments on the fly using closures. The closure must return a type that implements IntoIterator.

use comlexr::cmd;

let arr = vec![1, 2, 3];
let input = 2;

let command = cmd!(
    "echo",
    "test",
    || arr.into_iter().map(|i| format!("{}", i * input))
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "2" "4" "6""#.to_string());

Set Current Directory

Specify the directory to run the command.

use comlexr::cmd;

let command = cmd!(
    cd "~/";
    "echo",
    "test",
);

assert_eq!(format!("{command:?}"), r#"cd "~/" && "echo" "test""#);

Setting Environment Variables

Set environment variables for the command.

use comlexr::cmd;

const NEW_VAR: &str = "NEW_VAR";

let command = cmd!(
    env {
        "TEST": "test",
        NEW_VAR: "new_var"
    };
    "echo",
    "test",
);

assert_eq!(format!("{command:?}"), r#"NEW_VAR="new_var" TEST="test" "echo" "test""#);

Current Directory and Env Variable Order Matters

Environment variable declarations MUST come after the current directory declaration.

use comlexr::cmd;

let command = cmd!(
    cd "~/";
    env {
        "TEST": "test",
    };
    "echo",
    "test",
);

assert_eq!(
    format!("{command:?}"),
    r#"cd "~/" && TEST="test" "echo" "test""#
);

Features

  • Conditional expressions (if, if let)
  • Iteration constructs (for, for in)
  • Pattern matching (match)
  • Support for closures and dynamic expressions

Examples

See the tests directory for more examples on how to use comlexr effectively in your project.

License

This project is licensed under the MIT License.

Dependencies

~220–660KB
~16K SLoC