clap_runner/dispatch/
mod.rs1use 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}