tokio_process_tools/process/
builder.rs1use super::name::{ProcessName, generate_name};
2use super::stream_config::{ProcessStreamBuilder, ProcessStreamConfig};
3use crate::error::SpawnError;
4use crate::output_stream::OutputStream;
5use crate::process_handle::ProcessHandle;
6use std::marker::PhantomData;
7
8#[doc(hidden)]
9pub struct Unnamed;
10
11#[doc(hidden)]
12pub struct Named {
13 name: ProcessName,
14}
15
16#[doc(hidden)]
17pub struct Unset;
18
19pub struct Process<
48 NameState = Unnamed,
49 StdoutConfig = Unset,
50 Stdout = Unset,
51 StderrConfig = Unset,
52 Stderr = Unset,
53> {
54 cmd: tokio::process::Command,
55 name_state: NameState,
56 stdout_config: StdoutConfig,
57 stderr_config: StderrConfig,
58 _streams: PhantomData<fn() -> (Stdout, Stderr)>,
59}
60
61impl Process {
62 #[must_use]
64 pub fn new(cmd: tokio::process::Command) -> Self {
65 Self {
66 cmd,
67 name_state: Unnamed,
68 stdout_config: Unset,
69 stderr_config: Unset,
70 _streams: PhantomData,
71 }
72 }
73
74 #[must_use]
81 pub fn name(self, name: impl Into<ProcessName>) -> Process<Named> {
82 Process {
83 cmd: self.cmd,
84 name_state: Named { name: name.into() },
85 stdout_config: Unset,
86 stderr_config: Unset,
87 _streams: PhantomData,
88 }
89 }
90}
91
92impl Process<Named> {
93 #[must_use]
95 pub fn stdout_and_stderr<Config, Stream>(
96 self,
97 configure: impl FnOnce(ProcessStreamBuilder) -> Config,
98 ) -> Process<Named, Config, Stream, Config, Stream>
99 where
100 Config: ProcessStreamConfig<Stream> + Copy,
101 Stream: OutputStream,
102 {
103 let config = configure(ProcessStreamBuilder);
104 Process {
105 cmd: self.cmd,
106 name_state: self.name_state,
107 stdout_config: config,
108 stderr_config: config,
109 _streams: PhantomData,
110 }
111 }
112
113 #[must_use]
115 pub fn stdout<StdoutConfig, Stdout>(
116 self,
117 configure: impl FnOnce(ProcessStreamBuilder) -> StdoutConfig,
118 ) -> Process<Named, StdoutConfig, Stdout>
119 where
120 StdoutConfig: ProcessStreamConfig<Stdout>,
121 Stdout: OutputStream,
122 {
123 Process {
124 cmd: self.cmd,
125 name_state: self.name_state,
126 stdout_config: configure(ProcessStreamBuilder),
127 stderr_config: Unset,
128 _streams: PhantomData,
129 }
130 }
131
132 #[must_use]
134 pub fn stderr<StderrConfig, Stderr>(
135 self,
136 configure: impl FnOnce(ProcessStreamBuilder) -> StderrConfig,
137 ) -> Process<Named, Unset, Unset, StderrConfig, Stderr>
138 where
139 StderrConfig: ProcessStreamConfig<Stderr>,
140 Stderr: OutputStream,
141 {
142 Process {
143 cmd: self.cmd,
144 name_state: self.name_state,
145 stdout_config: Unset,
146 stderr_config: configure(ProcessStreamBuilder),
147 _streams: PhantomData,
148 }
149 }
150}
151
152impl<StdoutConfig, Stdout> Process<Named, StdoutConfig, Stdout>
153where
154 Stdout: OutputStream,
155{
156 #[must_use]
158 pub fn stderr<StderrConfig, Stderr>(
159 self,
160 configure: impl FnOnce(ProcessStreamBuilder) -> StderrConfig,
161 ) -> Process<Named, StdoutConfig, Stdout, StderrConfig, Stderr>
162 where
163 StdoutConfig: ProcessStreamConfig<Stdout>,
164 StderrConfig: ProcessStreamConfig<Stderr>,
165 Stderr: OutputStream,
166 {
167 Process {
168 cmd: self.cmd,
169 name_state: self.name_state,
170 stdout_config: self.stdout_config,
171 stderr_config: configure(ProcessStreamBuilder),
172 _streams: PhantomData,
173 }
174 }
175}
176
177impl<StderrConfig, Stderr> Process<Named, Unset, Unset, StderrConfig, Stderr>
178where
179 Stderr: OutputStream,
180{
181 #[must_use]
183 pub fn stdout<StdoutConfig, Stdout>(
184 self,
185 configure: impl FnOnce(ProcessStreamBuilder) -> StdoutConfig,
186 ) -> Process<Named, StdoutConfig, Stdout, StderrConfig, Stderr>
187 where
188 StderrConfig: ProcessStreamConfig<Stderr>,
189 StdoutConfig: ProcessStreamConfig<Stdout>,
190 Stdout: OutputStream,
191 {
192 Process {
193 cmd: self.cmd,
194 name_state: self.name_state,
195 stdout_config: configure(ProcessStreamBuilder),
196 stderr_config: self.stderr_config,
197 _streams: PhantomData,
198 }
199 }
200}
201
202impl<StdoutConfig, Stdout, StderrConfig, Stderr>
203 Process<Named, StdoutConfig, Stdout, StderrConfig, Stderr>
204where
205 Stdout: OutputStream,
206 Stderr: OutputStream,
207{
208 pub fn spawn(self) -> Result<ProcessHandle<Stdout, Stderr>, SpawnError>
214 where
215 StdoutConfig: ProcessStreamConfig<Stdout>,
216 StderrConfig: ProcessStreamConfig<Stderr>,
217 {
218 let name = generate_name(&self.name_state.name, &self.cmd);
219 ProcessHandle::<Stdout, Stderr>::spawn_with_stream_configs(
220 name,
221 self.cmd,
222 self.stdout_config,
223 self.stderr_config,
224 )
225 }
226}