Since there is a public API and there are various references to a rustfmt library in various issues here, it seems like it should be possible to use rustfmt as a library. However, most of the public API is not documented and I have not found a way of simply giving rustfmt some rust source code an having it format that.
I would appreciate this. This is the snippet I am using at the moment:
fn prettify_code(input: String) -> String {
let mut buf = Vec::new();
{
let mut config = rustfmt_nightly::Config::default();
config.set().emit_mode(rustfmt_nightly::EmitMode::Stdout);
config.set().edition(rustfmt_nightly::Edition::Edition2018);
let mut session = rustfmt_nightly::Session::new(config, Some(&mut buf));
session.format(rustfmt_nightly::Input::Text(input)).unwrap();
}
String::from_utf8(buf).unwrap()
}
And to confirm, this isn't possible on stable at the moment?
Currently in insta we're shelling out. This is a bit hacky (e.g. can't guarantee versions / it's even installed), but simple & works.
If there were a way of linking rustfmt that would be an interesting alternative.
fn format_rust_expression(value: &str) -> Cow<'_, str> {
const PREFIX: &str = "const x:() = ";
const SUFFIX: &str = ";\n";
if let Ok(mut proc) = Command::new("rustfmt")
.arg("--emit=stdout")
.arg("--edition=2018")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::null())
.spawn()
{
{
let stdin = proc.stdin.as_mut().unwrap();
stdin.write_all(PREFIX.as_bytes()).unwrap();
stdin.write_all(value.as_bytes()).unwrap();
stdin.write_all(SUFFIX.as_bytes()).unwrap();
}
if let Ok(output) = proc.wait_with_output() {
if output.status.success() {
// slice between after the prefix and before the suffix
// (currently 14 from the start and 2 before the end, respectively)
let start = PREFIX.len() + 1;
let end = output.stdout.len() - SUFFIX.len();
return str::from_utf8(&output.stdout[start..end])
.unwrap()
.to_owned()
.into();
}
}
}
Cow::Borrowed(value)
}
Most helpful comment
I would appreciate this. This is the snippet I am using at the moment: