ttvm 0.3.6

Runtime and compiler infrastructure API for Rust
Documentation
use mtk::{Lock, Error};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Handle {
    Stdout,
    Stdin,
    Stderr
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct IOHandle {
    stdout: (String, Lock),
    stdin: (String, Lock),
    stderr: (String, Lock)
}

impl IOHandle {
    pub fn new() -> IOHandle {
        IOHandle {
            stdout: (String::new(), Lock::new()),
            stdin: (String::new(), Lock::new()),
            stderr: (String::new(), Lock::new())
        }
    }

    pub fn print<S: AsRef<str>>(&mut self, handle: Handle, string: S) -> Result<usize, Error> {
        match handle {
            Handle::Stdout => {
                if !self.stdout.1.is_locked() {
                    self.stdout.1.lock();

                    self.stdout.0.push_str(string.as_ref());

                    self.stdout.1.unlock();

                    Ok(string.as_ref().len())
                } else {
                    Err(Error::from("stdout is locked"))
                }
            },
            Handle::Stderr => {
                if !self.stderr.1.is_locked() {
                    self.stderr.1.lock();

                    self.stderr.0.push_str(string.as_ref());

                    self.stderr.1.unlock();

                    Ok(string.as_ref().len())
                } else {
                    Err(Error::from("stderr is locked"))
                }
            },
            Handle::Stdin => Err(Error::from("cannot write to stdin"))
        }
    }

    pub fn read(&self, handle: Handle) -> Result<String, Error> {
        match handle {
            Handle::Stdout => Ok(self.stdout.0.clone()),
            Handle::Stderr => Ok(self.stderr.0.clone()),
            Handle::Stdin => Ok(read!("{}\n"))
        }
    }

    pub fn output(&self, handle: Handle) -> Result<usize, Error> {
        match handle {
            Handle::Stdout => {
                print!("{}", self.stdout.0);

                Ok(self.stdout.0.len())
            },
            Handle::Stderr => {
                print!("{}", self.stderr.0);

                Ok(self.stderr.0.len())
            },
            Handle::Stdin => Err(Error::from("cannot do output from stdin"))
        }
    }
}