shellfish/handler/asynchronous.rs
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
use std::collections::HashMap;
use async_trait::async_trait;
use yansi::Paint;
use crate::command::CommandType;
use crate::Command;
/// Async handler lets you run asynchronous commands. It also requires the
/// shell to be run in asynchronous mode to support it.
#[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;
}
/// Shellfish's default async handler. This handler is pretty simple, given
/// the only built in commands are `help`, `quit` and `exit`.
#[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() {
// Add some padding.
println!();
match command.as_str() {
"quit" | "exit" => return true,
"help" => {
println!("{}", description);
// Print information about built-in commands
println!(" help - displays help information.");
println!(" quit - quits the shell.");
println!(" exit - exits the shell.");
for (name, command) in commands {
println!(" {} - {}", name, command.help);
}
}
_ => {
// Attempt to find the command
let command = commands.get(&line[0] as &str);
// Checks if we got it
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]
)
}
}
}
}
// Padding
println!();
}
false
}
}