use std::{
io,
process::{
ChildStderr,
ChildStdin,
ChildStdout,
ExitStatus,
},
};
use process_wrap::std::ChildWrapper;
use super::success_status;
#[derive(Debug, Default)]
pub(super) struct NoStdinChild {
pub(super) stdin: Option<ChildStdin>,
pub(super) stdout: Option<ChildStdout>,
pub(super) stderr: Option<ChildStderr>,
pub(super) try_wait_error: Option<&'static str>,
pub(super) clear_try_wait_error_after_first: bool,
pub(super) pending: bool,
pub(super) exited_after_kill_attempt: bool,
pub(super) kill_attempted: bool,
pub(super) kill_error: Option<&'static str>,
pub(super) wait_error: Option<&'static str>,
}
impl ChildWrapper for NoStdinChild {
fn inner(&self) -> &dyn ChildWrapper {
self
}
fn inner_mut(&mut self) -> &mut dyn ChildWrapper {
self
}
fn into_inner(self: Box<Self>) -> Box<dyn ChildWrapper> {
self
}
fn stdin(&mut self) -> &mut Option<ChildStdin> {
&mut self.stdin
}
fn stdout(&mut self) -> &mut Option<ChildStdout> {
&mut self.stdout
}
fn stderr(&mut self) -> &mut Option<ChildStderr> {
&mut self.stderr
}
fn id(&self) -> u32 {
0
}
fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
if let Some(message) = self.try_wait_error {
if self.clear_try_wait_error_after_first {
self.try_wait_error = None;
}
Err(io::Error::other(message))
} else if self.pending && !(self.kill_attempted && self.exited_after_kill_attempt) {
Ok(None)
} else {
Ok(Some(success_status()))
}
}
fn wait(&mut self) -> io::Result<ExitStatus> {
if let Some(message) = self.wait_error {
Err(io::Error::other(message))
} else {
Ok(success_status())
}
}
fn start_kill(&mut self) -> io::Result<()> {
self.kill_attempted = true;
if let Some(message) = self.kill_error {
Err(io::Error::other(message))
} else {
Ok(())
}
}
}