use std::process::Stdio;
use tokio::process::{Child as TokioChild, ChildStderr, ChildStdout, Command as TokioCommand};
use crate::BoxedFuture;
mod pipe;
mod read;
mod write;
#[cfg(all(feature = "print", feature = "json"))]
mod cargo_preset;
#[cfg(feature = "print")]
mod print;
#[cfg(feature = "print")]
mod spinner;
pub mod config {
#[cfg(all(feature = "print", feature = "json"))]
pub use super::cargo_preset::Cargo;
pub use super::pipe::Pipe;
pub use super::read::Buffer;
pub use super::read::BufferString as String;
pub use super::read::CoLines;
pub use super::read::Lines;
#[cfg(feature = "print")]
pub use super::spinner::Spinner;
pub use super::write::Write;
}
pub mod task {
#[cfg(all(feature = "print", feature = "json"))]
pub use super::cargo_preset::CargoTask as Cargo;
pub use super::pipe::PipeTask as Pipe;
#[cfg(feature = "print")]
pub use super::print::PrintTask as Print;
pub use super::read::BufferStringTask as String;
pub use super::read::BufferTask as Buffer;
pub use super::read::CoLinesTask as CoLines;
pub use super::read::LinesTask as Lines;
#[cfg(feature = "print")]
pub use super::spinner::SpinnerTask as Spinner;
pub use super::write::WriteTask as Write;
}
pub mod output {
pub use super::pipe::PipeOutput as Pipe;
pub use super::read::CoLinesOutput as CoLines;
pub use super::read::LinesOutput as Lines;
}
pub use output::{CoLines, Lines, Pipe};
#[cfg(all(feature = "print", feature = "json"))]
pub use cargo_preset::cargo;
pub use pipe::pipe;
pub use read::{buffer, co_lines, lines, string};
#[cfg(feature = "print")]
pub use spinner::spinner;
pub use write::write;
#[cfg(feature = "print")]
mod print_driver;
#[cfg(feature = "print")]
use print_driver::*;
pub trait ChildOutConfig: Send + 'static {
type Task: ChildOutTask;
#[doc(hidden)]
type __Null;
fn configure_stdout(&mut self, command: &mut TokioCommand);
fn configure_stderr(&mut self, command: &mut TokioCommand);
fn take(
self,
child: &mut TokioChild,
name: Option<&str>,
is_out: bool,
) -> crate::Result<Self::Task>;
}
pub trait ChildInConfig: Send + 'static {
type Task: ChildInTask;
fn configure_stdin(&mut self, command: &mut TokioCommand) -> crate::Result<()>;
fn take(self, child: &mut TokioChild) -> crate::Result<Self::Task>;
}
pub trait ChildOutTask {
type Output: Send + 'static;
fn run(self) -> (Option<BoxedFuture<()>>, Self::Output);
}
pub trait ChildInTask {
fn run(self) -> Option<BoxedFuture<crate::Result<()>>>;
}
impl ChildOutTask for () {
type Output = ();
fn run(self) -> (Option<BoxedFuture<()>>, Self::Output) {
(None, ())
}
}
impl ChildInTask for () {
fn run(self) -> Option<BoxedFuture<crate::Result<()>>> {
None
}
}
#[doc(hidden)]
pub struct __OCNull;
#[doc(hidden)]
pub struct __OCNonNull;
#[derive(Clone, Copy)]
#[doc(hidden)]
pub struct Inherit;
pub fn inherit() -> Inherit {
Inherit
}
impl ChildOutConfig for Inherit {
type Task = ();
type __Null = __OCNull;
fn configure_stdout(&mut self, command: &mut TokioCommand) {
command.stdout(Stdio::inherit());
}
fn configure_stderr(&mut self, command: &mut TokioCommand) {
command.stderr(Stdio::inherit());
}
fn take(self, _: &mut TokioChild, _: Option<&str>, _: bool) -> crate::Result<()> {
Ok(())
}
}
impl ChildInConfig for Inherit {
type Task = ();
fn configure_stdin(&mut self, command: &mut TokioCommand) -> crate::Result<()> {
command.stdin(Stdio::inherit());
Ok(())
}
fn take(self, _: &mut TokioChild) -> crate::Result<()> {
Ok(())
}
}
#[derive(Clone, Copy)]
#[doc(hidden)]
pub struct Null;
pub fn null() -> Null {
Null
}
impl ChildOutConfig for Null {
type Task = ();
type __Null = __OCNull;
fn configure_stdout(&mut self, command: &mut TokioCommand) {
command.stdout(Stdio::null());
}
fn configure_stderr(&mut self, command: &mut TokioCommand) {
command.stderr(Stdio::null());
}
fn take(self, _: &mut TokioChild, _: Option<&str>, _: bool) -> crate::Result<()> {
Ok(())
}
}
impl ChildInConfig for Null {
type Task = ();
fn configure_stdin(&mut self, command: &mut TokioCommand) -> crate::Result<()> {
command.stdin(Stdio::null());
Ok(())
}
fn take(self, _: &mut TokioChild) -> crate::Result<()> {
Ok(())
}
}
pub(crate) fn take_child_out(
child: &mut TokioChild,
is_out: bool,
) -> crate::Result<Result<ChildStdout, ChildStderr>> {
if is_out {
let stdout = take_child_stdout(child)?;
Ok(Ok(stdout))
} else {
let stderr = take_child_stderr(child)?;
Ok(Err(stderr))
}
}
pub(crate) fn take_child_stdout(child: &mut TokioChild) -> crate::Result<ChildStdout> {
let Some(stdout) = child.stdout.take() else {
crate::bail!(
"failed to take stdout from child, possibly due to conflicting IO configuration."
);
};
Ok(stdout)
}
pub(crate) fn take_child_stderr(child: &mut TokioChild) -> crate::Result<ChildStderr> {
let Some(stdout) = child.stderr.take() else {
crate::bail!(
"failed to take stderr from child, possibly due to conflicting IO configuration."
);
};
Ok(stdout)
}