intelli_shell/process/
import.rs

1use color_eyre::Result;
2use futures_util::StreamExt;
3
4use super::{Process, ProcessOutput};
5use crate::{
6    cli::ImportCommandsProcess,
7    component::{
8        Component,
9        pick::{CommandsPickerComponent, CommandsPickerComponentMode},
10    },
11    config::Config,
12    errors::AppError,
13    format_error, format_msg,
14    process::InteractiveProcess,
15    service::IntelliShellService,
16};
17
18impl Process for ImportCommandsProcess {
19    async fn execute(self, config: Config, service: IntelliShellService) -> color_eyre::Result<ProcessOutput> {
20        let dry_run = self.dry_run;
21        let mut commands = match service.get_commands_from_location(self, config.gist).await {
22            Ok(s) => s,
23            Err(AppError::UserFacing(err)) => {
24                return Ok(ProcessOutput::fail().stderr(format_error!(config.theme, "{err}")));
25            }
26            Err(AppError::Unexpected(report)) => return Err(report),
27        };
28
29        if dry_run {
30            let mut stdout = String::new();
31            while let Some(command) = commands.next().await {
32                stdout += &command.map_err(AppError::into_report)?.to_string();
33                stdout += "\n";
34            }
35            if stdout.is_empty() {
36                Ok(ProcessOutput::fail().stderr(format_error!(&config.theme, "No commands were found")))
37            } else {
38                Ok(ProcessOutput::success().stdout(stdout))
39            }
40        } else {
41            match service.import_commands(commands, false).await {
42                Ok((0, 0)) => Ok(ProcessOutput::fail().stderr(format_error!(config.theme, "No commands were found"))),
43                Ok((0, skipped)) => {
44                    if dry_run {
45                        Ok(ProcessOutput::success())
46                    } else {
47                        Ok(ProcessOutput::success().stderr(format_msg!(
48                            config.theme,
49                            "No commands imported, {skipped} already existed"
50                        )))
51                    }
52                }
53                Ok((imported, 0)) => {
54                    if dry_run {
55                        Ok(ProcessOutput::success())
56                    } else {
57                        Ok(ProcessOutput::success()
58                            .stderr(format_msg!(config.theme, "Imported {imported} new commands")))
59                    }
60                }
61                Ok((imported, skipped)) => {
62                    if dry_run {
63                        Ok(ProcessOutput::success())
64                    } else {
65                        Ok(ProcessOutput::success().stderr(format_msg!(
66                            config.theme,
67                            "Imported {imported} new commands {}",
68                            config.theme.secondary.apply(format!("({skipped} already existed)"))
69                        )))
70                    }
71                }
72                Err(AppError::UserFacing(err)) => {
73                    Ok(ProcessOutput::fail().stderr(format_error!(config.theme, "{err}")))
74                }
75                Err(AppError::Unexpected(report)) => Err(report),
76            }
77        }
78    }
79}
80
81impl InteractiveProcess for ImportCommandsProcess {
82    fn into_component(self, config: Config, service: IntelliShellService, inline: bool) -> Result<Box<dyn Component>> {
83        Ok(Box::new(CommandsPickerComponent::new(
84            service,
85            config,
86            inline,
87            CommandsPickerComponentMode::Import { input: self },
88        )))
89    }
90}