xstream_util/
pool.rs

1//! A trait for a generic process pool used by xstream
2use std::borrow::BorrowMut;
3use std::error;
4use std::fmt;
5use std::fmt::{Display, Formatter};
6use std::io;
7use std::process::Child;
8
9/// Internal function to wait for a process
10///
11/// This will error in the event that it doesn't complete successfully (non-zero error code or
12/// otherwise)
13pub fn wait_proc(mut proc: impl BorrowMut<Child>) -> Result<(), Error> {
14    let status = proc.borrow_mut().wait().map_err(Error::Wait)?;
15    match status.code() {
16        Some(0) => Ok(()),
17        Some(code) => Err(Error::NonZeroExitCode(code)),
18        None => Err(Error::KilledBySignal),
19    }
20}
21
22/// An error raised by `xstream`
23#[non_exhaustive]
24#[derive(Debug)]
25pub enum Error {
26    /// The stdin to a child process wasn't piped
27    StdinNotPiped,
28    /// One of the spawned processes was killed by a signal
29    KilledBySignal,
30    /// One of the spawned processes returned a non-zero exit code
31    NonZeroExitCode(i32),
32    /// An error occured while trying to read from the input
33    Input(io::Error),
34    /// An error occured while trying to write to a child process
35    Output(io::Error),
36    /// An error occured while trying to spawn a child process
37    Spawn(io::Error),
38    /// An error occured while trying to wait for a child process
39    Wait(io::Error),
40}
41
42impl Display for Error {
43    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
44        write!(fmt, "{self:?}")
45    }
46}
47
48impl error::Error for Error {}
49
50/// A type that can `get` child processes on demand
51pub trait Pool {
52    /// Fetch a process from the pool
53    ///
54    /// Depending on the type of `Pool`, this may spawn a new process or just return one that is
55    /// already running.
56    ///
57    /// # Errors
58    ///
59    /// When anything goes wrong when trying to create a new process.
60    fn get(&mut self) -> Result<&mut Child, Error>;
61
62    /// Wait for all spawned processes to complete successfully
63    ///
64    /// # Errors
65    ///
66    /// When anything goes wrong when waiting for a process, including non-zero exit codes.
67    fn join(&mut self) -> Result<(), Error>;
68}