How to format a `TokenStream` with rustfmt?

I have generated some code with proc_macro2 and want to format it and write it to a file at a specified path. How should I do this? Inputting the string directly into rustfmt::format_input raises an error.

What error, specifically?

I just forget... Related with the "terminal"? Anyway it was weird.

Piping into stdin should work fine. It's what I've used before to clean up the output from a code generator.

I'm guessing the code you generated had a syntax error, and rustfmt wasn't able to recover from it.

1 Like

Finally I just write original tokenstream.to_string() to the dest file and then assert!(Command::new("rustfmt").arg(&path).status().unwrap().success());.

The error was failed to emit error: operation not supported by the terminal. Code below:

fn main() {
    let ibuf = something_outputs_tokenstream().to_string();
    let mut obuf = Vec::new();
    let mut ocur = std::io::Cursor::new(&mut obuf);
    let _ = rustfmt::format_input(rustfmt::Input::Text(ibuf), &Default::default(), Some(&mut ocur)).unwrap();
    println!("{}", String::from_utf8(obuf).unwrap());
}

Calling the CLI's rustfmt has never presented any problems.

Yeah, rustfmt is not designed to be a "public" Rust library crate; only a CLI binary.

For machine-generated output,

https://lib.rs/prettyplease

can be used as a Rust library and generates, in general, less weirdly formatted code (since machine-generated code can get weird, sometimes, and rustfmt was not made to account for such atypical cases in mind).

2 Likes

Thanks, it works well.