#![forbid(unsafe_code)]
#![warn(clippy::pedantic, clippy::dbg_macro, missing_docs)]
use proc_macro::TokenStream;
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{parse::Parse, parse_macro_input, punctuated::Punctuated, Expr, Result, Token};
mod cfstr;
use cfstr::CFStr;
#[proc_macro]
pub fn comat(input: TokenStream) -> TokenStream {
let str = parse_macro_input!(input as CFStr);
str.to_token_stream().into()
}
struct One {
cfstr: CFStr,
args: Punctuated<Expr, Token![,]>,
}
impl Parse for One {
fn parse(input: syn::parse::ParseStream) -> Result<Self> {
let cfstr = input.parse::<CFStr>()?;
let _ = input.parse::<Token![,]>();
Ok(Self {
cfstr,
args: Punctuated::<Expr, Token![,]>::parse_terminated(input)?,
})
}
}
impl ToTokens for One {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
self.cfstr.to_tokens(tokens);
tokens.append(proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone));
self.args.to_tokens(tokens);
}
}
#[proc_macro]
pub fn cprintln(input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as One);
quote! { println!(#f) }.into()
}
#[proc_macro]
pub fn cprint(input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as One);
quote! { print!(#f) }.into()
}
#[proc_macro]
pub fn cformat(input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as One);
quote! { format!(#f) }.into()
}
#[proc_macro]
pub fn cformat_args(input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as One);
quote! { format_args!(#f) }.into()
}
#[proc_macro]
pub fn cpanic(input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as One);
quote! { panic!(#f) }.into()
}
struct Two {
a: Expr,
cfstr: CFStr,
args: Punctuated<Expr, Token![,]>,
}
impl Parse for Two {
fn parse(input: syn::parse::ParseStream) -> Result<Self> {
let a = input.parse::<Expr>()?;
input.parse::<Token![,]>()?;
let cfstr = input.parse::<CFStr>()?;
let _ = input.parse::<Token![,]>();
Ok(Self {
a,
cfstr,
args: Punctuated::<Expr, Token![,]>::parse_terminated(input)?,
})
}
}
impl ToTokens for Two {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
self.a.to_tokens(tokens);
tokens.append(proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone));
self.cfstr.to_tokens(tokens);
tokens.append(proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone));
self.args.to_tokens(tokens);
}
}
#[proc_macro]
pub fn cwrite(input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as Two);
quote! { write!(#f) }.into()
}
#[proc_macro]
pub fn cwriteln(input: TokenStream) -> TokenStream {
let f = parse_macro_input!(input as Two);
quote! { writeln!(#f) }.into()
}