use crate::ffi::OsStr; use crate::fmt; use crate::io; use crate::marker::PhantomData; use crate::num::NonZeroI32; use crate::path::Path; use crate::sys::fs::File; use crate::sys::pipe::AnonPipe; use crate::sys::unsupported; use crate::sys_common::process::{CommandEnv, CommandEnvs}; pub use crate::ffi::OsString as EnvKey; //////////////////////////////////////////////////////////////////////////////// // Command //////////////////////////////////////////////////////////////////////////////// pub struct Command { env: CommandEnv, } // passed back to std::process with the pipes connected to the child, if any // were requested pub struct StdioPipes { pub stdin: Option, pub stdout: Option, pub stderr: Option, } pub enum Stdio { Inherit, Null, MakePipe, } impl Command { pub fn new(_program: &OsStr) -> Command { Command { env: Default::default() } } pub fn arg(&mut self, _arg: &OsStr) {} pub fn env_mut(&mut self) -> &mut CommandEnv { &mut self.env } pub fn cwd(&mut self, _dir: &OsStr) {} pub fn stdin(&mut self, _stdin: Stdio) {} pub fn stdout(&mut self, _stdout: Stdio) {} pub fn stderr(&mut self, _stderr: Stdio) {} pub fn get_program(&self) -> &OsStr { panic!("unsupported") } pub fn get_args(&self) -> CommandArgs<'_> { CommandArgs { _p: PhantomData } } pub fn get_envs(&self) -> CommandEnvs<'_> { self.env.iter() } pub fn get_current_dir(&self) -> Option<&Path> { None } pub fn spawn( &mut self, _default: Stdio, _needs_stdin: bool, ) -> io::Result<(Process, StdioPipes)> { unsupported() } } impl From for Stdio { fn from(pipe: AnonPipe) -> Stdio { pipe.diverge() } } impl From for Stdio { fn from(_file: File) -> Stdio { panic!("unsupported") } } impl fmt::Debug for Command { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) } } pub struct ExitStatus(!); impl ExitStatus { pub fn exit_ok(&self) -> Result<(), ExitStatusError> { self.0 } pub fn code(&self) -> Option { self.0 } } impl Clone for ExitStatus { fn clone(&self) -> ExitStatus { self.0 } } impl Copy for ExitStatus {} impl PartialEq for ExitStatus { fn eq(&self, _other: &ExitStatus) -> bool { self.0 } } impl Eq for ExitStatus {} impl fmt::Debug for ExitStatus { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0 } } impl fmt::Display for ExitStatus { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0 } } #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct ExitStatusError(ExitStatus); impl Into for ExitStatusError { fn into(self) -> ExitStatus { self.0.0 } } impl ExitStatusError { pub fn code(self) -> Option { self.0.0 } } #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct ExitCode(bool); impl ExitCode { pub const SUCCESS: ExitCode = ExitCode(false); pub const FAILURE: ExitCode = ExitCode(true); pub fn as_i32(&self) -> i32 { self.0 as i32 } } impl From for ExitCode { fn from(code: u8) -> Self { match code { 0 => Self::SUCCESS, 1..=255 => Self::FAILURE, } } } pub struct Process(!); impl Process { pub fn id(&self) -> u32 { self.0 } pub fn kill(&mut self) -> io::Result<()> { self.0 } pub fn wait(&mut self) -> io::Result { self.0 } pub fn try_wait(&mut self) -> io::Result> { self.0 } } pub struct CommandArgs<'a> { _p: PhantomData<&'a ()>, } impl<'a> Iterator for CommandArgs<'a> { type Item = &'a OsStr; fn next(&mut self) -> Option<&'a OsStr> { None } fn size_hint(&self) -> (usize, Option) { (0, Some(0)) } } impl<'a> ExactSizeIterator for CommandArgs<'a> {} impl<'a> fmt::Debug for CommandArgs<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().finish() } }