runestick/modules/
io.rs

1//! The `std::io` module.
2
3use crate::{ContextError, Module, Panic, Protocol, Stack, Value, VmError};
4use std::fmt;
5use std::fmt::Write as _;
6use std::io;
7use std::io::Write as _;
8
9/// Construct the `std::io` module.
10pub fn module(stdio: bool) -> Result<Module, ContextError> {
11    let mut module = Module::with_crate_item("std", &["io"]);
12
13    module.ty::<io::Error>()?;
14    module.inst_fn(Protocol::STRING_DISPLAY, format_io_error)?;
15
16    if stdio {
17        module.function(&["print"], print_impl)?;
18        module.function(&["println"], println_impl)?;
19        module.raw_fn(&["dbg"], dbg_impl)?;
20    }
21
22    Ok(module)
23}
24
25fn format_io_error(error: &std::io::Error, buf: &mut String) -> fmt::Result {
26    write!(buf, "{}", error)
27}
28
29fn dbg_impl(stack: &mut Stack, args: usize) -> Result<(), VmError> {
30    let stdout = io::stdout();
31    let mut stdout = stdout.lock();
32
33    for value in stack.drain_stack_top(args)? {
34        writeln!(stdout, "{:?}", value).map_err(VmError::panic)?;
35    }
36
37    stack.push(Value::Unit);
38    Ok(())
39}
40
41fn print_impl(m: &str) -> Result<(), Panic> {
42    let stdout = io::stdout();
43    let mut stdout = stdout.lock();
44    write!(stdout, "{}", m).map_err(Panic::custom)
45}
46
47fn println_impl(m: &str) -> Result<(), Panic> {
48    let stdout = io::stdout();
49    let mut stdout = stdout.lock();
50    writeln!(stdout, "{}", m).map_err(Panic::custom)
51}