s_crap/
cli.rs

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
19// TODO: refactor this interface so that there is no need to duplicate [dependecies] into [build-dependencies]
20pub trait CLI<'c> {
21	const NAME: &'c str;
22	const USAGE: &'c str;
23	// type Result: Try; // 👈 use this when trait `Try` become stable
24
25	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
41// pub type Result<U> = core::result::Result<U, Box<dyn error::Error>>;
42pub type Result<U> = core::result::Result<U, Box<dyn error::Error>>;