1use core::fmt;
4
5use crate as rune;
6use crate::alloc;
7use crate::alloc::fmt::TryWrite;
8use crate::alloc::prelude::*;
9use crate::compile;
10use crate::macros::{FormatArgs, MacroContext, TokenStream};
11use crate::parse::Parser;
12use crate::runtime::{EnvProtocolCaller, Format, Formatter, VmError};
13use crate::{ContextError, Module};
14
15#[rune::module(::std::fmt)]
27pub fn module() -> Result<Module, ContextError> {
28 let mut m = Module::from_meta(self::module__meta)?.with_unique("std::fmt");
29
30 m.ty::<Formatter>()?;
31 m.ty::<fmt::Error>()?;
32 m.function_meta(fmt_error_display_fmt)?;
33 m.macro_meta(format)?;
34
35 m.ty::<Format>()?;
36 m.function_meta(format_display_fmt__meta)?;
37 m.function_meta(format_debug_fmt__meta)?;
38 m.function_meta(format_clone__meta)?;
39 m.implement_trait::<Format>(rune::item!(::std::clone::Clone))?;
40
41 Ok(m)
42}
43
44#[rune::function(instance, protocol = DISPLAY_FMT)]
45fn fmt_error_display_fmt(error: &fmt::Error, f: &mut Formatter) -> alloc::Result<()> {
46 write!(f, "{error}")
47}
48
49#[rune::macro_(path = format)]
59pub(crate) fn format(
60 cx: &mut MacroContext<'_, '_, '_>,
61 stream: &TokenStream,
62) -> compile::Result<TokenStream> {
63 let mut p = Parser::from_token_stream(stream, cx.input_span());
64 let args = p.parse::<FormatArgs>()?;
65 p.eof()?;
66 let expanded = args.expand(cx)?;
67 Ok(expanded.into_token_stream(cx)?)
68}
69
70#[rune::function(keep, instance, protocol = DISPLAY_FMT)]
79fn format_display_fmt(format: &Format, f: &mut Formatter) -> Result<(), VmError> {
80 format
81 .spec
82 .format(&format.value, f, &mut EnvProtocolCaller)?;
83 Ok(())
84}
85
86#[rune::function(keep, instance, protocol = DEBUG_FMT)]
96fn format_debug_fmt(format: &Format, f: &mut Formatter) -> alloc::Result<()> {
97 write!(f, "{format:?}")
98}
99
100#[rune::function(keep, instance, protocol = CLONE)]
110fn format_clone(this: &Format) -> Result<Format, VmError> {
111 Ok(this.try_clone()?)
112}