gitignore_template_generator/
runner.rs

1//! Define components to process cli args.
2
3use crate::{
4    core::{
5        GitignoreTemplateManager, ProgramExit, QualifiedString, RemoteGitignoreTemplateManager,
6        TemplateFactory, TemplateManager,
7    },
8    parser::{Action, ArgsParser, ClapArgsParser},
9};
10
11pub type RunnerCallback<T, P> = fn(TemplateManagerRunner<T>, P);
12pub type MixedRunnerCallback = RunnerCallback<GitignoreTemplateManager, ClapArgsParser>;
13pub type RemoteRunnerCallback = RunnerCallback<RemoteGitignoreTemplateManager, ClapArgsParser>;
14
15pub type MixedRunner = TemplateManagerRunner<GitignoreTemplateManager>;
16pub type RemoteRunner = TemplateManagerRunner<RemoteGitignoreTemplateManager>;
17
18#[derive(Default)]
19pub struct TemplateManagerRunner<F: TemplateFactory<dyn TemplateManager>> {
20    _phantom_f: std::marker::PhantomData<F>,
21}
22
23impl<F: TemplateFactory<dyn TemplateManager>> TemplateManagerRunner<F> {
24    pub fn new() -> Self {
25        Self {
26            _phantom_f: std::marker::PhantomData,
27        }
28    }
29
30    pub fn exec(&self, parser: &impl ArgsParser) -> Result<QualifiedString, ProgramExit> {
31        let args = parser.parse(std::env::args_os());
32        let manager = F::from_args(&args)?;
33
34        let result = match args.to_action() {
35            Action::List => manager.list(),
36            Action::RobustGenerate => manager.generate_with_template_check(&args.template_names),
37            Action::Generate => manager.generate(&args.template_names),
38        };
39
40        self.parse_result(&result)
41    }
42
43    fn parse_result(
44        &self,
45        result: &Result<QualifiedString, ProgramExit>,
46    ) -> Result<QualifiedString, ProgramExit> {
47        match result {
48            Ok(output) if output.value.is_empty() => Ok(QualifiedString::empty(output.kind)),
49            Ok(output) => Ok(output.clone()),
50            Err(error) => Err(error.clone()),
51        }
52    }
53}
54
55pub fn get_parser() -> ClapArgsParser {
56    ClapArgsParser::new()
57}
58
59cfg_if::cfg_if! {
60    if #[cfg(feature = "local_templating")] {
61        pub fn start(callback: MixedRunnerCallback) {
62            callback(MixedRunner::new(), get_parser());
63        }
64    } else {
65        pub fn start(callback: RemoteRunnerCallback) {
66            callback(RemoteRunner::new(), get_parser());
67        }
68    }
69}