1use crate::{arg, commands::*};
2use clap::{App, ArgMatches, SubCommand};
3use std::error;
4
5#[rustfmt::skip]
6pub fn build<'a, 'b>() -> App<'a, 'b> {
7 Main::command()
8 .subcommand(Eval::command())
9 .subcommand(Code::command())
10}
11
12pub fn run(matches: &ArgMatches) -> Result<()> {
13 Main::run_on(&matches)?;
14 Eval::run_on(&matches)?;
15 Code::run_on(&matches)?;
16 Ok(())
17}
18
19pub trait CLI<'c> {
21 const NAME: &'c str;
22 const USAGE: &'c str;
23 fn additional_usage<'s>(cmd: App<'s, 'c>) -> App<'s, 'c>;
26 fn command<'s: 'c>() -> App<'c, 's> {
27 let cmd = SubCommand::with_name(Self::NAME);
28 Self::additional_usage(cmd).args_from_usage(Self::USAGE)
29 }
30
31 fn invoke(args: &ArgMatches) -> Result<()>;
32 fn run_on(matches: &ArgMatches) -> Result<()> {
33 if let Some(args) = matches.subcommand_matches(Self::NAME) {
34 arg::output::validate(args)?;
35 Self::invoke(args)?;
36 }
37 Ok(())
38 }
39}
40
41pub type Result<U> = core::result::Result<U, Box<dyn error::Error>>;