diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-09 12:15:21 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-09 12:15:53 +0900 |
| commit | f18c18cd15f180b5067069ec6f10530515715f3d (patch) | |
| tree | 85ea3d3f10da9b32359dc3797fc7e6d262ae6752 /crates/mozart-console-macros/src | |
| parent | f0192390ae1d89981f59395307e885a595f86eef (diff) | |
| download | php-mozart-f18c18cd15f180b5067069ec6f10530515715f3d.tar.gz php-mozart-f18c18cd15f180b5067069ec6f10530515715f3d.tar.zst php-mozart-f18c18cd15f180b5067069ec6f10530515715f3d.zip | |
refactor(console): accept format args directly in console_writeln! macros
Eliminate the nested &console_format!(...) boilerplate at every call site
by teaching console_writeln!, console_write!, console_writeln_error!, and
console_write_error! to accept a format literal + variadic args directly,
matching the println!/eprintln! ergonomics. Propagate the format string
span into generated code so rustc errors point to the right location.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart-console-macros/src')
| -rw-r--r-- | crates/mozart-console-macros/src/codegen.rs | 21 | ||||
| -rw-r--r-- | crates/mozart-console-macros/src/lib.rs | 6 |
2 files changed, 21 insertions, 6 deletions
diff --git a/crates/mozart-console-macros/src/codegen.rs b/crates/mozart-console-macros/src/codegen.rs index 002f808..8601e07 100644 --- a/crates/mozart-console-macros/src/codegen.rs +++ b/crates/mozart-console-macros/src/codegen.rs @@ -77,10 +77,11 @@ fn count_positional_placeholders(s: &str) -> usize { pub fn generate( segments: &[Segment], extra_args: &Punctuated<Expr, syn::Token![,]>, + span: proc_macro2::Span, ) -> TokenStream { // Single segment: pass all extra args if segments.len() == 1 { - return generate_single(&segments[0], extra_args); + return generate_single(&segments[0], extra_args, span); } // Multiple segments: distribute positional args across segments @@ -101,7 +102,7 @@ pub fn generate( pos = end; let ident = quote::format_ident!("__seg{}", i); - let expr = generate_single(segment, &slice); + let expr = generate_single(segment, &slice, span); seg_bindings.push(quote! { let #ident = #expr; }); seg_idents.push(ident); } @@ -124,11 +125,21 @@ fn segment_content(segment: &Segment) -> &str { } } -fn generate_single(segment: &Segment, args: &Punctuated<Expr, syn::Token![,]>) -> TokenStream { +fn spanned_lit(s: &str, span: proc_macro2::Span) -> proc_macro2::Literal { + let mut lit = proc_macro2::Literal::string(s); + lit.set_span(span); + lit +} + +fn generate_single( + segment: &Segment, + args: &Punctuated<Expr, syn::Token![,]>, + span: proc_macro2::Span, +) -> TokenStream { match segment { Segment::Plain(text) => { if has_placeholders(text) { - let lit = proc_macro2::Literal::string(text); + let lit = spanned_lit(text, span); quote! { ::std::format!(#lit, #args) } } else { quote! { ::std::string::String::from(#text) } @@ -137,7 +148,7 @@ fn generate_single(segment: &Segment, args: &Punctuated<Expr, syn::Token![,]>) - Segment::Tagged { tag, content } => { let func = quote::format_ident!("__format_{}_message", tag); if has_placeholders(content) { - let lit = proc_macro2::Literal::string(content); + let lit = spanned_lit(content, span); quote! { ::std::string::ToString::to_string( &::mozart_core::console::#func(&::std::format!(#lit, #args)) diff --git a/crates/mozart-console-macros/src/lib.rs b/crates/mozart-console-macros/src/lib.rs index 3af6f82..0678ecd 100644 --- a/crates/mozart-console-macros/src/lib.rs +++ b/crates/mozart-console-macros/src/lib.rs @@ -39,7 +39,11 @@ fn console_format_impl( let args: ConsoleFormatArgs = syn::parse2(input)?; let segments = parser::parse_format_string(&args.format_str) .map_err(|msg| syn::Error::new(args.format_str_span, msg))?; - Ok(codegen::generate(&segments, &args.extra_args)) + Ok(codegen::generate( + &segments, + &args.extra_args, + args.format_str_span, + )) } struct ConsoleFormatArgs { |
