rustfmt_config_proc_macro/
utils.rs

1use proc_macro2::TokenStream;
2use quote::{ToTokens, quote};
3
4pub fn fold_quote<F, I, T>(input: impl Iterator<Item = I>, f: F) -> TokenStream
5where
6    F: Fn(I) -> T,
7    T: ToTokens,
8{
9    input.fold(quote! {}, |acc, x| {
10        let y = f(x);
11        quote! { #acc #y }
12    })
13}
14
15pub fn is_unit(v: &syn::Variant) -> bool {
16    match v.fields {
17        syn::Fields::Unit => true,
18        _ => false,
19    }
20}
21
22#[cfg(feature = "debug-with-rustfmt")]
23/// Pretty-print the output of proc macro using rustfmt.
24pub fn debug_with_rustfmt(input: &TokenStream) {
25    use std::env;
26    use std::ffi::OsStr;
27    use std::io::Write;
28    use std::process::{Command, Stdio};
29
30    let rustfmt_var = env::var_os("RUSTFMT");
31    let rustfmt = match &rustfmt_var {
32        Some(rustfmt) => rustfmt,
33        None => OsStr::new("rustfmt"),
34    };
35    let mut child = Command::new(rustfmt)
36        .stdin(Stdio::piped())
37        .stdout(Stdio::piped())
38        .spawn()
39        .expect("Failed to spawn rustfmt in stdio mode");
40    {
41        let stdin = child.stdin.as_mut().expect("Failed to get stdin");
42        stdin
43            .write_all(format!("{}", input).as_bytes())
44            .expect("Failed to write to stdin");
45    }
46    let rustfmt_output = child.wait_with_output().expect("rustfmt has failed");
47
48    eprintln!(
49        "{}",
50        String::from_utf8(rustfmt_output.stdout).expect("rustfmt returned non-UTF8 string")
51    );
52}