1#[cfg(feature = "std")]
4use std::io::{self, Write as _};
5
6use crate as rune;
7#[cfg(feature = "std")]
8use crate::alloc;
9#[cfg(feature = "std")]
10use crate::alloc::fmt::TryWrite;
11use crate::compile;
12use crate::macros::{quote, FormatArgs, MacroContext, TokenStream};
13use crate::parse::Parser;
14#[cfg(feature = "std")]
15use crate::runtime::{Address, Formatter, Memory, Output, VmError};
16use crate::{docstring, ContextError, Module};
17
18#[rune::module(::std::io)]
20pub fn module(
21 #[cfg_attr(not(feature = "std"), allow(unused))] stdio: bool,
22) -> Result<Module, ContextError> {
23 let mut m = Module::from_meta(self::module__meta)?.with_unique("std::io");
24
25 m.item_mut().docs(docstring! {
26 })?;
40
41 #[cfg(feature = "std")]
42 m.ty::<io::Error>()?;
43 #[cfg(feature = "std")]
44 m.function_meta(io_error_display_fmt)?;
45 #[cfg(feature = "std")]
46 m.function_meta(io_error_debug_fmt)?;
47
48 #[cfg(feature = "std")]
49 if stdio {
50 m.function_meta(print_impl)?;
51 m.function_meta(println_impl)?;
52
53 m.raw_function("dbg", dbg_impl).build()?.docs(docstring! {
54 })?;
72 }
73
74 m.macro_meta(dbg_macro)?;
77 m.macro_meta(print_macro)?;
78 m.macro_meta(println_macro)?;
79 Ok(m)
80}
81
82#[rune::function(instance, protocol = DISPLAY_FMT)]
83#[cfg(feature = "std")]
84fn io_error_display_fmt(error: &io::Error, f: &mut Formatter) -> alloc::Result<()> {
85 write!(f, "{error}")
86}
87
88#[rune::function(instance, protocol = DEBUG_FMT)]
89#[cfg(feature = "std")]
90fn io_error_debug_fmt(error: &io::Error, f: &mut Formatter) -> alloc::Result<()> {
91 write!(f, "{error:?}")
92}
93
94#[cfg(feature = "std")]
95fn dbg_impl(
96 memory: &mut dyn Memory,
97 addr: Address,
98 args: usize,
99 out: Output,
100) -> Result<(), VmError> {
101 let stdout = io::stdout();
102 let mut stdout = stdout.lock();
103
104 for value in memory.slice_at(addr, args)? {
105 writeln!(stdout, "{value:?}").map_err(VmError::panic)?;
106 }
107
108 memory.store(out, ())?;
109 Ok(())
110}
111
112#[rune::macro_(path = dbg)]
131pub(crate) fn dbg_macro(
132 cx: &mut MacroContext<'_, '_, '_>,
133 stream: &TokenStream,
134) -> compile::Result<TokenStream> {
135 Ok(quote!(::std::io::dbg(#stream)).into_token_stream(cx)?)
136}
137
138#[rune::macro_(path = print)]
150pub(crate) fn print_macro(
151 cx: &mut MacroContext<'_, '_, '_>,
152 stream: &TokenStream,
153) -> compile::Result<TokenStream> {
154 let mut p = Parser::from_token_stream(stream, cx.input_span());
155 let args = p.parse_all::<FormatArgs>()?;
156 let expanded = args.expand(cx)?;
157 Ok(quote!(::std::io::print(#expanded)).into_token_stream(cx)?)
158}
159
160#[rune::function(path = print)]
174#[cfg(feature = "std")]
175fn print_impl(m: &str) -> Result<(), VmError> {
176 let stdout = io::stdout();
177 let mut stdout = stdout.lock();
178 write!(stdout, "{m}").map_err(VmError::panic)?;
179 Ok(())
180}
181
182#[rune::macro_(path = println)]
194pub(crate) fn println_macro(
195 cx: &mut MacroContext<'_, '_, '_>,
196 stream: &TokenStream,
197) -> compile::Result<TokenStream> {
198 let mut p = Parser::from_token_stream(stream, cx.input_span());
199 let args = p.parse_all::<FormatArgs>()?;
200 let expanded = args.expand(cx)?;
201 Ok(quote!(::std::io::println(#expanded)).into_token_stream(cx)?)
202}
203
204#[rune::function(path = println)]
216#[cfg(feature = "std")]
217fn println_impl(message: &str) -> Result<(), VmError> {
218 let stdout = io::stdout();
219 let mut stdout = stdout.lock();
220 writeln!(stdout, "{message}").map_err(VmError::panic)?;
221 Ok(())
222}