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