intelli_shell/process/
import.rs1use std::time::Duration;
2
3use color_eyre::Result;
4use futures_util::StreamExt;
5use indicatif::{ProgressBar, ProgressStyle};
6use tokio_util::sync::CancellationToken;
7
8use super::{Process, ProcessOutput};
9use crate::{
10 cli::ImportItemsProcess,
11 component::{
12 Component,
13 pick::{ImportExportPickerComponent, ImportExportPickerComponentMode},
14 },
15 config::Config,
16 errors::AppError,
17 format_error,
18 process::InteractiveProcess,
19 service::IntelliShellService,
20 widgets::SPINNER_CHARS,
21};
22
23impl Process for ImportItemsProcess {
24 async fn execute(
25 self,
26 config: Config,
27 service: IntelliShellService,
28 cancellation_token: CancellationToken,
29 ) -> color_eyre::Result<ProcessOutput> {
30 let dry_run = self.dry_run;
31
32 let res = if self.ai {
34 let pb = ProgressBar::new_spinner();
36 pb.set_style(
37 ProgressStyle::with_template("{spinner:.blue} {wide_msg}")
38 .unwrap()
39 .tick_strings(&SPINNER_CHARS),
40 );
41 pb.enable_steady_tick(Duration::from_millis(100));
42 pb.set_message("Thinking ...");
43
44 let res = service
46 .get_items_from_location(self, config.gist, cancellation_token)
47 .await;
48
49 pb.finish_and_clear();
51
52 res
53 } else {
54 service
56 .get_items_from_location(self, config.gist, cancellation_token)
57 .await
58 };
59
60 let mut items = match res {
62 Ok(s) => s,
63 Err(AppError::UserFacing(err)) => {
64 return Ok(ProcessOutput::fail().stderr(format_error!(config.theme, "{err}")));
65 }
66 Err(AppError::Unexpected(report)) => return Err(report),
67 };
68
69 if dry_run {
71 let mut stdout = String::new();
72 while let Some(item) = items.next().await {
73 stdout += &item.map_err(AppError::into_report)?.to_string();
74 stdout += "\n";
75 }
76 if stdout.is_empty() {
77 Ok(ProcessOutput::fail().stderr(format_error!(&config.theme, "No commands or completions were found")))
78 } else {
79 Ok(ProcessOutput::success().stdout(stdout))
80 }
81 } else {
82 match service.import_items(items, false).await {
84 Ok(stats) => Ok(stats.into_output(&config.theme)),
85 Err(AppError::UserFacing(err)) => {
86 Ok(ProcessOutput::fail().stderr(format_error!(config.theme, "{err}")))
87 }
88 Err(AppError::Unexpected(report)) => Err(report),
89 }
90 }
91 }
92}
93
94impl InteractiveProcess for ImportItemsProcess {
95 fn into_component(
96 self,
97 config: Config,
98 service: IntelliShellService,
99 inline: bool,
100 cancellation_token: CancellationToken,
101 ) -> Result<Box<dyn Component>> {
102 Ok(Box::new(ImportExportPickerComponent::new(
103 service,
104 config,
105 inline,
106 ImportExportPickerComponentMode::Import { input: self },
107 cancellation_token,
108 )))
109 }
110}