pistonite_cu/process/pio/
mod.rs1use std::process::Stdio;
52
53use tokio::process::{Child as TokioChild, ChildStderr, ChildStdout, Command as TokioCommand};
54
55use crate::BoxedFuture;
56
57mod pipe;
58mod read;
59mod write;
60
61#[cfg(all(feature = "print", feature = "json"))]
62mod cargo_preset;
63#[cfg(feature = "print")]
64mod print;
65#[cfg(feature = "print")]
66mod spinner;
67
68pub mod config {
70 #[cfg(all(feature = "print", feature = "json"))]
71 pub use super::cargo_preset::Cargo;
72 pub use super::pipe::Pipe;
73 pub use super::read::Buffer;
74 pub use super::read::BufferString as String;
75 pub use super::read::CoLines;
76 pub use super::read::Lines;
77 #[cfg(feature = "print")]
78 pub use super::spinner::Spinner;
79 pub use super::write::Write;
80}
81
82pub mod task {
84 #[cfg(all(feature = "print", feature = "json"))]
85 pub use super::cargo_preset::CargoTask as Cargo;
86 pub use super::pipe::PipeTask as Pipe;
87 #[cfg(feature = "print")]
88 pub use super::print::PrintTask as Print;
89 pub use super::read::BufferStringTask as String;
90 pub use super::read::BufferTask as Buffer;
91 pub use super::read::CoLinesTask as CoLines;
92 pub use super::read::LinesTask as Lines;
93 #[cfg(feature = "print")]
94 pub use super::spinner::SpinnerTask as Spinner;
95 pub use super::write::WriteTask as Write;
96}
97
98pub mod output {
100 pub use super::pipe::PipeOutput as Pipe;
101 pub use super::read::CoLinesOutput as CoLines;
102 pub use super::read::LinesOutput as Lines;
103}
104
105pub use output::{CoLines, Lines, Pipe};
107#[cfg(all(feature = "print", feature = "json"))]
109pub use cargo_preset::cargo;
110pub use pipe::pipe;
111pub use read::{buffer, co_lines, lines, string};
112#[cfg(feature = "print")]
113pub use spinner::spinner;
114pub use write::write;
115
116#[cfg(feature = "print")]
117mod print_driver;
118#[cfg(feature = "print")]
119use print_driver::*;
120
121pub trait ChildOutConfig: Send + 'static {
132 type Task: ChildOutTask;
133 #[doc(hidden)]
134 type __Null;
135 fn configure_stdout(&mut self, command: &mut TokioCommand);
137 fn configure_stderr(&mut self, command: &mut TokioCommand);
139
140 fn take(
152 self,
153 child: &mut TokioChild,
154 name: Option<&str>,
155 is_out: bool,
156 ) -> crate::Result<Self::Task>;
157}
158
159pub trait ChildInConfig: Send + 'static {
169 type Task: ChildInTask;
170 fn configure_stdin(&mut self, command: &mut TokioCommand) -> crate::Result<()>;
172 fn take(self, child: &mut TokioChild) -> crate::Result<Self::Task>;
174}
175
176pub trait ChildOutTask {
178 type Output: Send + 'static;
179
180 fn run(self) -> (Option<BoxedFuture<()>>, Self::Output);
185}
186pub trait ChildInTask {
188 fn run(self) -> Option<BoxedFuture<crate::Result<()>>>;
193}
194impl ChildOutTask for () {
195 type Output = ();
196 fn run(self) -> (Option<BoxedFuture<()>>, Self::Output) {
197 (None, ())
198 }
199}
200impl ChildInTask for () {
201 fn run(self) -> Option<BoxedFuture<crate::Result<()>>> {
202 None
203 }
204}
205
206#[doc(hidden)]
207pub struct __OCNull;
208#[doc(hidden)]
209pub struct __OCNonNull;
210
211#[derive(Clone, Copy)]
212#[doc(hidden)]
213pub struct Inherit;
214pub fn inherit() -> Inherit {
216 Inherit
217}
218impl ChildOutConfig for Inherit {
219 type Task = ();
220 type __Null = __OCNull;
221 fn configure_stdout(&mut self, command: &mut TokioCommand) {
222 command.stdout(Stdio::inherit());
223 }
224 fn configure_stderr(&mut self, command: &mut TokioCommand) {
225 command.stderr(Stdio::inherit());
226 }
227 fn take(self, _: &mut TokioChild, _: Option<&str>, _: bool) -> crate::Result<()> {
228 Ok(())
229 }
230}
231impl ChildInConfig for Inherit {
232 type Task = ();
233 fn configure_stdin(&mut self, command: &mut TokioCommand) -> crate::Result<()> {
234 command.stdin(Stdio::inherit());
235 Ok(())
236 }
237 fn take(self, _: &mut TokioChild) -> crate::Result<()> {
238 Ok(())
239 }
240}
241#[derive(Clone, Copy)]
242#[doc(hidden)]
243pub struct Null;
244pub fn null() -> Null {
246 Null
247}
248impl ChildOutConfig for Null {
249 type Task = ();
250 type __Null = __OCNull;
251 fn configure_stdout(&mut self, command: &mut TokioCommand) {
252 command.stdout(Stdio::null());
253 }
254 fn configure_stderr(&mut self, command: &mut TokioCommand) {
255 command.stderr(Stdio::null());
256 }
257 fn take(self, _: &mut TokioChild, _: Option<&str>, _: bool) -> crate::Result<()> {
258 Ok(())
259 }
260}
261impl ChildInConfig for Null {
262 type Task = ();
263 fn configure_stdin(&mut self, command: &mut TokioCommand) -> crate::Result<()> {
264 command.stdin(Stdio::null());
265 Ok(())
266 }
267 fn take(self, _: &mut TokioChild) -> crate::Result<()> {
268 Ok(())
269 }
270}
271
272pub(crate) fn take_child_out(
273 child: &mut TokioChild,
274 is_out: bool,
275) -> crate::Result<Result<ChildStdout, ChildStderr>> {
276 if is_out {
277 let stdout = take_child_stdout(child)?;
278 Ok(Ok(stdout))
279 } else {
280 let stderr = take_child_stderr(child)?;
281 Ok(Err(stderr))
282 }
283}
284pub(crate) fn take_child_stdout(child: &mut TokioChild) -> crate::Result<ChildStdout> {
285 let Some(stdout) = child.stdout.take() else {
286 crate::bail!(
287 "failed to take stdout from child, possibly due to conflicting IO configuration."
288 );
289 };
290 Ok(stdout)
291}
292pub(crate) fn take_child_stderr(child: &mut TokioChild) -> crate::Result<ChildStderr> {
293 let Some(stdout) = child.stderr.take() else {
294 crate::bail!(
295 "failed to take stderr from child, possibly due to conflicting IO configuration."
296 );
297 };
298 Ok(stdout)
299}