/* * Copyright (C) 2023 Valentin Lorentz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use std::collections::HashMap; use clap::{ArgMatches, Command, Parser}; use color_eyre::eyre::{anyhow, bail, Result, WrapErr}; use tokio::sync::mpsc; use crate::action::Action; pub type CommandHandler = Box) -> Result<()>>; pub trait RataCommand { fn name(&self) -> String; fn help(&self) -> String; fn handler(&self) -> CommandHandler; } pub struct RataCommands(pub HashMap>); impl RataCommands { pub fn new() -> RataCommands { RataCommands(HashMap::new()) } pub fn register(&mut self, command: Box) { if let Some(previous_command) = self.0.insert(command.name(), command) { log::info!("Overriding existing command {}", previous_command.name()); } } } /* pub fn parser() -> Command { inventory::iter::().fold( Command::new("ratatrix") .bin_name("") .subcommand_required(true), |parser, command| { if command.command.get_bin_name().is_none() { panic!("Command {:?} has no bin_name", command.command); } parser.subcommand(command.command.clone()) }, ) }*/ pub fn run_command( command_line: &str, app: &crate::App, action_tx: &mpsc::UnboundedSender, ) -> Result<()> { if command_line.bytes().nth(0) != Some(b'/') { bail!("Not a command: {}", command_line); } let (command_name, args) = match command_line[1..].split_once(" ") { Some((command_name, args)) => (command_name, args), None => (&command_line[1..], ""), }; match app.commands.0.get(&command_name.to_ascii_lowercase()) { Some(command) => command.handler()(command_name, args, app, action_tx), None => bail!("Unknown command /{}", command_name), } }