clap_runner/dispatch/
mod.rs

1use crate::{context::Context, error::*};
2use faststr::FastStr;
3use std::collections::HashMap;
4
5use crate::command::BoxSafeRunnableCommand;
6
7mod inner;
8mod model;
9
10pub struct Dispatcher {
11    handlers_finder: HashMap<FastStr, tokio::sync::Mutex<BoxSafeRunnableCommand>>,
12    cmd: clap::Command,
13}
14
15impl Dispatcher {
16    pub fn new<H: Into<BoxSafeRunnableCommand>>(h: H) -> Result<Self> {
17        let h: BoxSafeRunnableCommand = h.into();
18        h.self_check()?;
19
20        let cmd = h.0.command();
21        let mut handlers_finder = HashMap::new();
22        handlers_finder.insert(FastStr::new(cmd.get_name()), tokio::sync::Mutex::new(h));
23        Ok(Self {
24            handlers_finder,
25            cmd,
26        })
27    }
28
29    pub fn register<H: Into<BoxSafeRunnableCommand>>(mut self, h: H) -> Result<Self> {
30        let h: BoxSafeRunnableCommand = h.into();
31        h.self_check()?;
32
33        let cmd = h.0.command();
34        self.handlers_finder
35            .insert(FastStr::new(cmd.get_name()), tokio::sync::Mutex::new(h));
36        self.cmd = self.cmd.subcommand(cmd);
37
38        Ok(self)
39    }
40
41    pub async fn dispatch_with_stdio(self) -> Result<Context> {
42        let cx = Context::new_stdout();
43        let matches = self.cmd.clone().get_matches();
44        self.dispatch_inner(cx, matches).await
45    }
46
47    pub async fn dispatch<I, T, O>(
48        self,
49        i: I,
50        o: std::sync::Arc<tokio::sync::Mutex<O>>,
51    ) -> Result<Context>
52    where
53        O: crate::context::OutputBound,
54        I: IntoIterator<Item = T>,
55        T: Into<std::ffi::OsString> + Clone,
56    {
57        let cx = Context::new_with_output(o);
58        let matches = self.cmd.clone().get_matches_from(i);
59        self.dispatch_inner(cx, matches).await
60    }
61}