pistonite_cu/process/pio/
pipe.rs1use std::process::Stdio;
2
3use tokio::process::{Child as TokioChild, Command as TokioCommand};
4
5use crate::{BoxedFuture, Context as _};
6
7use super::{ChildInConfig, ChildOutConfig, ChildOutTask};
8
9#[inline(always)]
31pub fn pipe() -> Pipe {
32 Pipe
33}
34pub struct Pipe;
35impl ChildOutConfig for Pipe {
36 type Task = PipeTask;
37 type __Null = super::__OCNonNull;
38
39 fn configure_stdout(&mut self, command: &mut TokioCommand) {
40 command.stdout(std::process::Stdio::piped());
41 }
42
43 fn configure_stderr(&mut self, command: &mut TokioCommand) {
44 command.stderr(std::process::Stdio::piped());
45 }
46
47 fn take(
48 self,
49 child: &mut TokioChild,
50 _name: Option<&str>,
51 is_out: bool,
52 ) -> crate::Result<Self::Task> {
53 let stream = super::take_child_out(child, is_out)?;
54 let x: Result<Stdio, _> = match stream {
60 Ok(s) => s.try_into(),
61 Err(s) => s.try_into(),
62 };
63 let x = x.context("failed to convert tokio pipe to std pipe")?;
64 Ok(PipeTask(x))
65 }
66}
67pub struct PipeTask(Stdio);
68impl ChildOutTask for PipeTask {
69 type Output = PipeOutput;
70 fn run(self) -> (Option<BoxedFuture<()>>, Self::Output) {
71 (None, PipeOutput(Some(self.0)))
72 }
73}
74
75pub struct PipeOutput(Option<Stdio>); impl ChildInConfig for PipeOutput {
78 type Task = ();
79
80 fn configure_stdin(&mut self, command: &mut TokioCommand) -> crate::Result<()> {
81 match self.0.take() {
82 Some(x) => {
83 command.stdin(x);
84 Ok(())
85 }
86 _ => crate::bail!("unexpected: pipe was already taken"),
87 }
88 }
89
90 fn take(self, _: &mut TokioChild) -> crate::Result<Self::Task> {
91 Ok(())
92 }
93}