cliproc 2.1.1

A fast, low-level, and configurable command-line processor
Documentation
use cliproc::{cli, proc};
use cliproc::{stage::Memory, Arg, Cli, Command, ExitCode, Help, Subcommand};
use std::env;

#[derive(Debug, PartialEq)]
struct Calc {
    version: bool,
    force: bool,
    op: Option<Operation>,
}

impl Command for Calc {
    fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
        Ok(Calc {
            force: cli.check(Arg::flag("force"))?,
            version: cli.check(Arg::flag("version"))?,
            op: cli.nest(Arg::subcommand("operation"))?,
        })
    }

    fn execute(self) -> proc::Result {
        if self.version == true {
            println!("1.0.0");
            Ok(())
        } else {
            if self.force == true {
                println!("Force enabled in base command!");
            }
            if let Some(op) = self.op {
                op.execute(&())
            } else {
                Ok(())
            }
        }
    }
}

#[derive(Debug, PartialEq)]
enum Operation {
    Add(Add),
    Mult(Mult),
}

impl Subcommand<()> for Operation {
    fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
        match cli.select(&["add", "mult"])?.as_ref() {
            "add" => Ok(Operation::Add(Add::interpret(cli)?)),
            "mult" => Ok(Operation::Mult(Mult::interpret(cli)?)),
            _ => panic!("an unimplemented command was passed through!"),
        }
    }

    fn execute(self, c: &()) -> proc::Result {
        match self {
            Operation::Add(op) => op.execute(&c),
            Operation::Mult(op) => op.execute(&c),
        }
    }
}

#[derive(Debug, PartialEq)]
struct Add {
    lhs: u32,
    rhs: u32,
    force: bool,
    verbose: bool,
}

impl Subcommand<()> for Add {
    fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
        cli.help(Help::with("Addition"))?;
        Ok(Add {
            force: cli.check(Arg::flag("force"))?,
            verbose: cli.check(Arg::flag("verbose"))?,
            lhs: cli.require(Arg::positional("lhs"))?,
            rhs: cli.require(Arg::positional("rhs"))?,
        })
    }

    fn execute(self, _: &()) -> proc::Result {
        let sum = self.lhs + self.rhs;
        if self.force == true {
            println!("Force enabled in subcommand!");
        }
        match self.verbose {
            true => println!("{} + {} = {}", self.lhs, self.rhs, sum),
            false => println!("{}", sum),
        }
        Ok(())
    }
}

#[derive(Debug, PartialEq)]
struct Mult {
    lhs: f32,
    rhs: f32,
}

impl Subcommand<()> for Mult {
    fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
        cli.help(Help::with("Multiplication"))?;
        Ok(Mult {
            lhs: cli.require(Arg::positional("lhs"))?,
            rhs: cli.require(Arg::positional("rhs"))?,
        })
    }

    fn execute(self, _: &()) -> proc::Result {
        let prod = self.lhs * self.rhs;
        println!("{} x {} = {}", self.lhs, self.rhs, prod);
        Ok(())
    }
}

fn main() -> ExitCode {
    Cli::default().parse(env::args()).go::<Calc>()
}