mddd_std/runners/
leaf.rs

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}