color_print_proc_macro/
lib.rs1extern crate proc_macro;
6
7#[macro_use]
8mod util;
9#[cfg(not(feature = "terminfo"))]
10mod ansi;
11#[cfg(not(feature = "terminfo"))]
12mod ansi_constants;
13mod color_context;
14mod error;
15mod format_args;
16mod parse;
17#[cfg(feature = "terminfo")]
18mod terminfo;
19mod untagged;
20
21use proc_macro::TokenStream;
22use quote::{quote, ToTokens};
23use syn::{
24 parse::{Parse, ParseStream},
25 parse_macro_input,
26 token::Comma,
27 Expr,
28};
29
30#[proc_macro]
40#[cfg(not(feature = "terminfo"))]
41pub fn cformat(input: TokenStream) -> TokenStream {
42 get_macro("format", input, false)
43}
44
45#[proc_macro]
47#[cfg(feature = "terminfo")]
48pub fn cformat(input: TokenStream) -> TokenStream {
49 get_macro("format", input, false)
50}
51
52#[proc_macro]
61#[cfg(not(feature = "terminfo"))]
62pub fn cprint(input: TokenStream) -> TokenStream {
63 get_macro("print", input, false)
64}
65
66#[proc_macro]
68#[cfg(feature = "terminfo")]
69pub fn cprint(input: TokenStream) -> TokenStream {
70 get_macro("print", input, false)
71}
72
73#[proc_macro]
82#[cfg(not(feature = "terminfo"))]
83pub fn ceprint(input: TokenStream) -> TokenStream {
84 get_macro("eprint", input, false)
85}
86
87#[proc_macro]
89#[cfg(feature = "terminfo")]
90pub fn ceprint(input: TokenStream) -> TokenStream {
91 get_macro("eprint", input, false)
92}
93
94#[proc_macro]
103#[cfg(not(feature = "terminfo"))]
104pub fn cprintln(input: TokenStream) -> TokenStream {
105 get_macro("println", input, false)
106}
107
108#[proc_macro]
110#[cfg(feature = "terminfo")]
111pub fn cprintln(input: TokenStream) -> TokenStream {
112 get_macro("println", input, false)
113}
114
115#[proc_macro]
124#[cfg(not(feature = "terminfo"))]
125pub fn ceprintln(input: TokenStream) -> TokenStream {
126 get_macro("eprintln", input, false)
127}
128
129#[proc_macro]
131#[cfg(feature = "terminfo")]
132pub fn ceprintln(input: TokenStream) -> TokenStream {
133 get_macro("eprintln", input, false)
134}
135
136#[proc_macro]
138#[cfg(not(feature = "terminfo"))]
139pub fn cwrite(input: TokenStream) -> TokenStream {
140 get_macro("write", input, true)
141}
142
143#[proc_macro]
145#[cfg(feature = "terminfo")]
146pub fn cwrite(input: TokenStream) -> TokenStream {
147 get_macro("write", input, true)
148}
149
150#[proc_macro]
152#[cfg(not(feature = "terminfo"))]
153pub fn cwriteln(input: TokenStream) -> TokenStream {
154 get_macro("writeln", input, true)
155}
156
157#[proc_macro]
159#[cfg(feature = "terminfo")]
160pub fn cwriteln(input: TokenStream) -> TokenStream {
161 get_macro("writeln", input, true)
162}
163
164#[cfg(not(feature = "terminfo"))]
177#[proc_macro]
178pub fn cstr(input: TokenStream) -> TokenStream {
179 crate::ansi::get_cstr(input)
180 .unwrap_or_else(|err| err.to_token_stream())
181 .into()
182}
183
184#[proc_macro]
196pub fn untagged(input: TokenStream) -> TokenStream {
197 crate::untagged::get_untagged(input)
198 .unwrap_or_else(|err| err.to_token_stream())
199 .into()
200}
201
202#[cfg(feature = "terminfo")]
207#[proc_macro]
208pub fn cstr(_: TokenStream) -> TokenStream {
209 panic!("Macro cstr!() cannot be used with terminfo feature")
210}
211
212struct WriteInput {
213 dst: Expr,
214 rest: TokenStream,
215}
216
217impl Parse for WriteInput {
218 fn parse(input: ParseStream) -> syn::parse::Result<Self> {
219 let dst: Expr = input.parse()?;
220 let _: Comma = input.parse()?;
221 let rest = input.parse_terminated(Expr::parse, Comma)?;
222 let rest = quote! { #rest }.into(); Ok(Self { dst, rest })
224 }
225}
226
227fn get_macro(macro_name: &str, input: TokenStream, is_write_macro: bool) -> TokenStream {
229 let macro_name = util::ident(macro_name);
230 let fmt_args = |input_tail| {
231 #[cfg(not(feature = "terminfo"))]
232 let format_args = crate::ansi::get_format_args(input_tail);
233 #[cfg(feature = "terminfo")]
234 let format_args = crate::terminfo::get_format_args(input_tail);
235 format_args.unwrap_or_else(|err| err.to_token_stream())
236 };
237
238 if is_write_macro {
239 let WriteInput { dst, rest } = parse_macro_input!(input);
240 let format_args = fmt_args(rest);
241 (quote! { #macro_name!(#dst, #format_args) }).into()
242 } else {
243 let format_args = fmt_args(input);
244 (quote! { #macro_name!(#format_args) }).into()
245 }
246}