use std::collections::HashMap;
use yansi::Paint;
use crate::command::CommandType;
use crate::Command;
pub trait Handler<T> {
fn handle(
&self,
args: Vec<String>,
commands: &HashMap<&str, Command<T>>,
state: &mut T,
description: &str,
) -> bool;
}
#[derive(Default, Copy, Clone, Eq, PartialEq)]
pub struct DefaultHandler();
impl<T> Handler<T> for DefaultHandler {
fn handle(
&self,
line: Vec<String>,
commands: &HashMap<&str, Command<T>>,
state: &mut T,
description: &str,
) -> bool {
if let Some(command) = line.first() {
println!();
match command.as_str() {
"quit" | "exit" => return true,
"help" => {
println!("{}", description);
println!(" help - displays help information.");
println!(" quit - quits the shell.");
println!(" exit - exits the shell.");
for (name, command) in commands {
println!(" {} - {}", name, command.help);
}
}
_ => {
let command = commands.get(&*line[0]);
match command {
Some(command) => {
if let Err(e) = match command.command {
CommandType::Sync(c) => c(state, line),
#[cfg(feature = "async")]
CommandType::Async(_) => {
eprintln!("{}", Paint::red("Async commands cannot be run in sync shells."));
Ok(())
}
} {
eprintln!("{}", Paint::red(&format!("Command exited unsuccessfully:\n{}\n({:?})", &e, &e)))
}
}
None => {
eprintln!(
"{} {}",
Paint::red("Command not found:"),
line[0]
)
}
}
}
}
println!();
}
false
}
}