#instructions #command #engine #string #execution #transform #default

command-engine

Transform string instructions into code execution

2 releases (1 stable)

1.0.0 Apr 29, 2024
1.0.0-rc.1 Apr 27, 2024

#896 in Parser implementations

Download history 89/week @ 2024-04-21 270/week @ 2024-04-28 5/week @ 2024-05-05 5/week @ 2024-05-19

369 downloads per month

GPL-3.0-only

23KB
459 lines

Command Engine

Transform string instructions into code execution.

Engine

This crate provides a default engine, that is present if default features are enabled. It is simply a container for your Commands that can also execute them based on the input.

There are 2 versions of the default Engine:

  • sync - Default.
  • async - Enabled with async feature.

Instruction

The given input is deserialized into a specific format defined in Instruction structure.

It allows for one Command caller, multiple positional args, additional o_args which act like flags that can contain sub_args.

Format:

<caller> <arg> <arg> --<o_arg> <sub_arg> <sub_arg> --<o_arg>

Example:

example argument1 argument2 --flag2 child1 child2 --flag3 --flag1

Deserializes to:

Instruction {
    caller: "example",
    args: vec!["argument1", "argument2"],
    o_args: {
        let mut map = HashMap::new();
        map.insert("--flag2", Some(vec!["child1", "child2"]));
        map.insert("--flag3", None);
        map.insert("--flag1", None);
        map
    },
    input: "example argument1 argument2 --flag2 child1 child2 --flag3 --flag1",
};

To add spaces in arguments use double quotes ":

example "argument 1" "--flag 2" "child 1"

If there are double quotes in the argument it's suggested to use collector #:

example #"argument "quotes" 1"#

There are no escape characters to avoid any heap allocations. Each argument is a string slice taken from the input.

Example

Sync version:

use command_engine::*;

pub struct Example;

impl CommandInfo for Example {
    fn caller(&self) -> &'static str {
        "ex"
    }
}

impl Command for Example {
    type Output = String;

    fn on_execute(&self, ins: Instruction) -> Self::Output {
        format!("{:?}", ins)
    }
}

fn main() {
    let input = "ex arg --o_arg sub_arg";
    
    let mut engine = Engine::new();
    engine.insert(Example);
    
    // Will return formatted string of the Instruction.
    let output = engine.execute(input).unwrap();
    println!("{}", output);
}

Disclaimer

ToDo (in future):

  • Custom Instructions (just like the Outputs)
  • Integrated help command

Versioning:

  • *.*.* - Released.
  • *.*.*-rc.* - Release Candidate.
  • *.*.*-dev - Unreleased in production.
  • 0.*.* - Deprecated.

Dependencies

~0–1.1MB
~19K SLoC