use std::collections::HashMap;
use async_trait::async_trait;
use yansi::Paint;
use crate::command::CommandType;
use crate::Command;
#[async_trait]
pub trait AsyncHandler<T: Send> {
async fn handle_async(
&self,
args: Vec<String>,
commands: &HashMap<&str, Command<T>>,
state: &mut T,
description: &str,
) -> bool;
}
#[derive(Default, Copy, Clone, Eq, PartialEq)]
pub struct DefaultAsyncHandler();
#[async_trait]
impl<T: Send> AsyncHandler<T> for DefaultAsyncHandler {
async fn handle_async(
&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] as &str);
match command {
Some(command) => {
if let Err(e) = match command.command {
CommandType::Sync(c) => c(state, line),
#[cfg(feature = "async")]
CommandType::Async(a) => a(state, line).await,
} {
eprintln!("{}", Paint::red(&format!("Command exited unsuccessfully:\n{}\n({:?})", &e, &e)))
}
}
None => {
eprintln!(
"{} {}",
Paint::red("Command not found:"),
line[0]
)
}
}
}
}
println!();
}
false
}
}