ru_shell 0.1.0

A Shell built around a semantic grammar
use crate::args::Args;
use crate::channel::*;
use crate::store::Store;
use err_tools::*;
use std::process::{Child, Command, Stdio};

#[derive(Clone, Debug)]
pub struct Connection {
    pub chan: Channel,
    pub target: Box<Exec>,
}

impl Connection {
    pub fn run(
        &self,
        ch: Child,
        sets: &mut Store,
        out: Stdio,
        err: Stdio,
    ) -> anyhow::Result<Child> {
        let iread = self
            .chan
            .as_reader(ch.stdout.e_str("No output")?, ch.stderr.e_str("No errput")?);

        self.target.run(sets, iread.to_stdio(), out, err)
    }
}

#[derive(Clone, Debug)]
pub struct Exec {
    pub command: String,
    pub args: Args,
    pub conn: Option<Connection>,
}

impl Exec {
    pub fn run(
        &self,
        s: &mut Store,
        input: Stdio,
        output: Stdio,
        errput: Stdio,
    ) -> anyhow::Result<Child> {
        match &self.conn {
            None => Command::new(&self.command)
                .args(self.args.run(s)?)
                .stdin(input)
                .stdout(output)
                .stderr(errput)
                .spawn()
                .map_err(Into::into),

            Some(conn) => {
                let ch = Command::new(&self.command)
                    .args(self.args.run(s)?)
                    .stdin(input)
                    .stdout(Stdio::piped())
                    .stderr(Stdio::piped())
                    .spawn()?;
                conn.run(ch, s, output, errput)
            }
        }
    }
}