use std::path::PathBuf;
use conciliator::Claw;
use clap::{
CommandFactory,
Subcommand,
Parser
};
use clap_complete::Shell;
use crate::Nunc;
use crate::error::Result;
macro_rules! ret_errmsg {
($($args:tt)*) => {
return Err($crate::error::Error::Message(format!($($args)*)))
};
}
pub mod arg;
pub mod cmd;
use cmd::*;
#[derive(Parser)]
pub struct Cli {
#[clap(short, long)]
config: Option<PathBuf>,
#[clap(long)]
generate_completions: Option<Shell>,
#[clap(subcommand)]
cmd: Option<Cmd>
}
#[derive(Subcommand)]
enum Cmd {
#[clap(flatten)]
Log(log::Cmd),
#[clap(flatten)]
Review(review::Cmd),
#[clap(flatten)]
Manage(manage::Cmd),
#[clap(subcommand)]
Zone(zone::Cmd),
}
impl Cli {
#[cfg(not(test))]
pub fn run(self, con: &Claw) -> Result<()> {
let nunc = match &self.config {
Some(path) => Nunc::load_with_config(path)?,
None => Nunc::load()?
};
if let Some(shell) = self.generate_completions {
clap_complete::generate(
shell,
&mut Self::command(),
"nunc",
&mut std::io::stdout()
);
return Ok(());
}
match self.cmd {
Some(cmd) => cmd.run(con, &nunc),
None => Ok(())
}
}
}
#[cfg(test)]
impl Cli {
fn test_run(self, nunc: &Nunc, con: &Claw) -> Result<()> {
match self.cmd {
Some(cmd) => cmd.run(con, nunc),
None => Ok(())
}
}
}
#[cfg(test)]
pub struct Tester {
nunc: Nunc,
con: Claw
}
#[cfg(test)]
impl Tester {
pub fn init() -> Result<Self> {
Ok(Self {
nunc: Nunc::testing()?,
con: conciliator::init()
})
}
pub fn run<'s>(&self, args: impl IntoIterator<Item=&'s str>) -> Result<()> {
use conciliator::{
Color,
Conciliator,
Paint
};
let mut cmd_line = self.con.line(..);
cmd_line.tag(Color::Iota, "TEST")
.push("nunc_test");
let args_tee = args.into_iter().inspect(|arg| {
cmd_line.push(" ").push(arg);
});
let cli = Cli::try_parse_from(
["nunc_test"].into_iter().chain(args_tee)
).unwrap();
cmd_line.print();
cli.test_run(&self.nunc, &self.con).inspect_err(|err| {
self.con.error(err);
})
}
}
impl Cmd {
fn run(self, con: &Claw, nunc: &Nunc) -> Result<()> {
match self {
Cmd::Log(cmd) => cmd.run(con, nunc),
Cmd::Review(cmd) => cmd.run(con, nunc),
Cmd::Manage(cmd) => cmd.run(con, nunc),
Cmd::Zone(cmd) => cmd.run(con, nunc),
}
}
}
#[test]
fn clap() {
Cli::command().debug_assert();
}
#[test]
fn empty_dummy() -> Result<()> {
Tester::init()?.run([""; 0])
}