clapcmd 0.3.3

A readline wrapper that allows for creating custom interactive shells, similar to python's cmd module
Documentation
use crate::group::HandlerGroupMeta;
use crate::ClapCmd;
use clap::ArgMatches;

pub type ClapCmdResult = Result<(), Box<dyn std::error::Error>>;

pub trait Callback<State>: CallbackClone<State> + Sync + Send
where
    State: Clone,
{
    fn call(&self, cmd: &mut ClapCmd<State>, matches: ArgMatches) -> ClapCmdResult;
}

impl<State, F> Callback<State> for F
where
    State: Clone + Sync + Send,
    F: Clone + 'static + Sync + Send,
    F: for<'r> Fn(&mut ClapCmd<State>, ArgMatches) -> ClapCmdResult,
{
    fn call(&self, cmd: &mut ClapCmd<State>, matches: ArgMatches) -> ClapCmdResult {
        self(cmd, matches)
    }
}

pub trait CallbackClone<State> {
    fn clone_box(&self) -> Box<dyn Callback<State>>;
}

impl<T, State> CallbackClone<State> for T
where
    T: Callback<State> + Clone + 'static,
    State: Clone,
{
    fn clone_box(&self) -> Box<dyn Callback<State>> {
        Box::new(self.clone())
    }
}

pub struct Handler<State> {
    pub(crate) command: clap::Command,
    pub(crate) group: Option<HandlerGroupMeta>,
    pub(crate) callback: Box<dyn Callback<State>>,
}

impl<State> Clone for Handler<State> {
    fn clone(&self) -> Self {
        Self {
            command: self.command.clone(),
            group: self.group.clone(),
            callback: self.callback.clone_box(),
        }
    }
}