1use std::marker::PhantomData;
2use std::mem;
3
4use mddd_traits::{IRunner, IUseCase, IUseCaseRequest};
5
6use crate::constants::HELP_KEYS;
7use crate::runners::helper::make_leaf_help;
8use crate::runners::main_executor;
9use crate::utils::print_n_exit;
10
11pub struct LeafRunner<UC, R, E> {
12 constructor: Box<dyn FnOnce() -> UC>,
13 phantom: PhantomData<(UC, R, E)>,
14}
15
16impl<R: IUseCaseRequest, E: std::fmt::Debug, UC: IUseCase<Request = R, Error = E>>
17 LeafRunner<UC, R, E>
18{
19 pub fn new(constructor: impl FnOnce() -> UC + 'static) -> Self {
20 Self {
21 constructor: Box::new(constructor),
22 phantom: PhantomData::default(),
23 }
24 }
25
26 pub fn run(self) {
27 main_executor::run(self)
28 }
29}
30
31impl<R: IUseCaseRequest, E: std::fmt::Debug, UC: IUseCase<Request = R, Error = E>> IRunner
32 for LeafRunner<UC, R, E>
33{
34 fn short_description(&self) -> String {
35 UC::short_description()
36 }
37
38 fn execute(&mut self, prefix: &str, args: &[&str]) {
39 let plug: Box<dyn FnOnce() -> UC> = Box::new(|| -> UC { unreachable!() });
40 let constructor = mem::replace(&mut self.constructor, plug);
41 let mut uc: UC = constructor();
42 if !args.is_empty() && HELP_KEYS.contains(&args[0]) {
43 let help = make_leaf_help::<R, UC>(prefix, &uc);
44 println!("{}", help);
45 return;
46 }
47 let request = match R::build(args) {
48 Ok(val) => val,
49 Err(err) => print_n_exit(&err),
50 };
51 if let Err(err) = uc.execute(request) {
52 print_n_exit(&format!("{:?}", err))
53 }
54 }
55}