mxsh 0.2.0

Embeddable POSIX-style shell parser and runtime
Documentation
use std::collections::VecDeque;
use std::io;

use mxsh::ShellBuilder;
use mxsh::advanced::SessionState;
use mxsh::embed::StdioConfig;
use mxsh::frontend::InteractiveFrontend;
use mxsh::runtime::testing::{InMemoryRuntime, StringStdioOut};

struct QueueFrontend {
    lines: VecDeque<String>,
}

impl InteractiveFrontend for QueueFrontend {
    fn prompt(&mut self, _shell: &SessionState, _continuation: bool) -> io::Result<String> {
        Ok(String::new())
    }

    fn read_line(
        &mut self,
        _shell: &mut SessionState,
        _prompt: &str,
    ) -> io::Result<Option<String>> {
        Ok(self.lines.pop_front())
    }
}

fn main() {
    let stdout = StringStdioOut::new();
    let mut shell = ShellBuilder::new()
        .interactive(true)
        .stdio(StdioConfig {
            stdout: stdout.fd(),
            ..StdioConfig::default()
        })
        .build(InMemoryRuntime::new())
        .expect("shell should build");
    let mut frontend = QueueFrontend {
        lines: VecDeque::from(["echo hello".to_string(), "exit".to_string()]),
    };

    let result = shell
        .run_interactive_with_frontend(&mut frontend)
        .expect("interactive shell should succeed");
    assert_eq!(result.exit_code, Some(0));
    assert!(stdout.collect().contains("hello"));
}