intelli_shell/process/mod.rs
1use clap::{Args, FromArgMatches};
2
3use crate::{component::Component, config::Config, service::IntelliShellService};
4
5pub mod export;
6pub mod fix;
7pub mod import;
8pub mod new;
9pub mod replace;
10pub mod search;
11pub mod tldr_clear;
12pub mod tldr_fetch;
13
14#[cfg(debug_assertions)]
15pub mod query;
16
17/// Represents the final outcome of a [`Process`] execution.
18///
19/// This enum determines the action the shell should take after a command has been processed.
20/// It can either lead to the execution of a new shell command or result in exiting the process with specific output
21/// information.
22pub enum ProcessOutput {
23 /// Instructs the shell to execute the specified command
24 Execute { cmd: String },
25 /// Instructs the shell to terminate and output the provided information
26 Output(OutputInfo),
27}
28
29/// Holds the information to be written to output streams upon process termination.
30///
31/// This structure defines what should be sent to standard output (stdout), standard error (stderr), and/or a dedicated
32/// file, along with a status indicating if the operation itself succeeded or failed.
33#[derive(Clone, PartialEq, Eq, Default)]
34#[cfg_attr(debug_assertions, derive(Debug))]
35pub struct OutputInfo {
36 /// Indicates whether the operation that generated this output bundle was considered a failure
37 pub failed: bool,
38
39 /// Content to be written to a specified output file.
40 ///
41 /// When this is `Some`, it typically takes precedence over `stdout`. This is useful for redirecting the main
42 /// output of a command to a file, for instance, via an `--output` flag.
43 pub fileout: Option<String>,
44
45 /// Content to be written to the standard output (stdout) stream.
46 ///
47 /// This is generally used when no file output is specified.
48 pub stdout: Option<String>,
49
50 /// Content to be written to the standard error (stderr) stream.
51 ///
52 /// Used for error messages or diagnostic information.
53 pub stderr: Option<String>,
54}
55
56impl ProcessOutput {
57 /// Creates a [`ProcessOutput::Execute`] variant to run a shell command
58 pub fn execute(cmd: impl Into<String>) -> Self {
59 Self::Execute { cmd: cmd.into() }
60 }
61
62 /// Creates a successful [`ProcessOutput::Output`] with no content and succesful exit code
63 pub fn success() -> Self {
64 Self::Output(OutputInfo {
65 failed: false,
66 ..Default::default()
67 })
68 }
69
70 /// Creates a failed [`ProcessOutput::Output`] with no content and failure exit code
71 pub fn fail() -> Self {
72 Self::Output(OutputInfo {
73 failed: true,
74 ..Default::default()
75 })
76 }
77
78 /// Sets the file output content for the [`ProcessOutput::Output`] variant.
79 ///
80 /// Note: This has no effect if the instance is a `ProcessOutput::Execute` variant.
81 pub fn fileout(self, fileout: impl Into<String>) -> Self {
82 match self {
83 e @ ProcessOutput::Execute { .. } => e,
84 ProcessOutput::Output(data) => ProcessOutput::Output(OutputInfo {
85 fileout: Some(fileout.into()),
86 ..data
87 }),
88 }
89 }
90
91 /// Sets the standard output content for the [`ProcessOutput::Output`] variant.
92 ///
93 /// Note: This has no effect if the instance is a `ProcessOutput::Execute` variant.
94 pub fn stdout(self, stdout: impl Into<String>) -> Self {
95 match self {
96 e @ ProcessOutput::Execute { .. } => e,
97 ProcessOutput::Output(data) => ProcessOutput::Output(OutputInfo {
98 stdout: Some(stdout.into()),
99 ..data
100 }),
101 }
102 }
103
104 /// Sets the standard error content for the [`ProcessOutput::Output`] variant.
105 ///
106 /// Note: This has no effect if the instance is a `ProcessOutput::Execute` variant.
107 pub fn stderr(self, stderr: impl Into<String>) -> Self {
108 match self {
109 e @ ProcessOutput::Execute { .. } => e,
110 ProcessOutput::Output(data) => ProcessOutput::Output(OutputInfo {
111 stderr: Some(stderr.into()),
112 ..data
113 }),
114 }
115 }
116}
117
118/// Trait for non-interactive processes
119#[trait_variant::make(Send)]
120pub trait Process {
121 /// Executes the process non-interactively and returns the output
122 async fn execute(self, config: Config, service: IntelliShellService) -> color_eyre::Result<ProcessOutput>;
123}
124
125/// Trait for interactive processes
126pub trait InteractiveProcess: Process + FromArgMatches + Args {
127 /// Converts the process into a renderable component
128 fn into_component(
129 self,
130 config: Config,
131 service: IntelliShellService,
132 inline: bool,
133 ) -> color_eyre::Result<Box<dyn Component>>;
134}