mirror of
https://gitee.com/openharmony/third_party_rust_bindgen
synced 2025-03-04 12:47:22 +00:00
lib: rustfmt output to stdout
Simplify the rustfmt and write mechanism. Use rustfmt generated string to allow writing to stdout or to rustfmt a file.
This commit is contained in:
parent
a08d8fd65f
commit
d5d962332b
126
src/lib.rs
126
src/lib.rs
@ -1652,18 +1652,13 @@ impl Bindings {
|
|||||||
|
|
||||||
/// Write these bindings as source text to a file.
|
/// Write these bindings as source text to a file.
|
||||||
pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
||||||
{
|
let file = OpenOptions::new()
|
||||||
let file = try!(
|
.write(true)
|
||||||
OpenOptions::new()
|
.truncate(true)
|
||||||
.write(true)
|
.create(true)
|
||||||
.truncate(true)
|
.open(path.as_ref())?;
|
||||||
.create(true)
|
self.write(Box::new(file))?;
|
||||||
.open(path.as_ref())
|
Ok(())
|
||||||
);
|
|
||||||
self.write(Box::new(file))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.rustfmt_generated_file(path.as_ref())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write these bindings as source text to the given `Write`able.
|
/// Write these bindings as source text to the given `Write`able.
|
||||||
@ -1676,31 +1671,52 @@ impl Bindings {
|
|||||||
writer.write(line.as_bytes())?;
|
writer.write(line.as_bytes())?;
|
||||||
writer.write("\n".as_bytes())?;
|
writer.write("\n".as_bytes())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.options.raw_lines.is_empty() {
|
if !self.options.raw_lines.is_empty() {
|
||||||
writer.write("\n".as_bytes())?;
|
writer.write("\n".as_bytes())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.write(self.module.as_str().as_bytes())?;
|
let bindings = self.module.as_str().to_string();
|
||||||
|
|
||||||
|
match self.rustfmt_generated_string(bindings) {
|
||||||
|
Ok(rustfmt_bindings) => {
|
||||||
|
writer.write(rustfmt_bindings.as_str().as_bytes())?;
|
||||||
|
},
|
||||||
|
Err(err) => eprintln!("{:?}", err),
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if rustfmt_bindings is set and runs rustfmt on the file
|
/// Checks if rustfmt_bindings is set and runs rustfmt on the string
|
||||||
fn rustfmt_generated_file(&self, file: &Path) -> io::Result<()> {
|
fn rustfmt_generated_string(&self, source: String) -> io::Result<String> {
|
||||||
let _t = time::Timer::new("rustfmt_generated_file")
|
let _t = time::Timer::new("rustfmt_generated_string")
|
||||||
.with_output(self.options.time_phases);
|
.with_output(self.options.time_phases);
|
||||||
|
|
||||||
if !self.options.rustfmt_bindings {
|
if !self.options.rustfmt_bindings {
|
||||||
return Ok(());
|
return Ok(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
let rustfmt = if let Ok(rustfmt) = which::which("rustfmt") {
|
let rustfmt = if let Ok(rustfmt) = which::which("rustfmt") {
|
||||||
rustfmt
|
rustfmt
|
||||||
} else {
|
} else {
|
||||||
warn!("Not running rustfmt because it does not exist in PATH");
|
eprintln!("warning: could not find usable rustfmt to pretty print bindings");
|
||||||
return Ok(());
|
return Ok(source);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cmd = Command::new(rustfmt);
|
// Prefer using the `rustfmt-nightly` version of `rustmft`, if
|
||||||
|
// possible. It requires being run via `rustup run nightly ...`.
|
||||||
|
let mut cmd = if let Ok(rustup) = which::which("rustup") {
|
||||||
|
let mut cmd = Command::new(rustup);
|
||||||
|
cmd.args(&["run", "nightly", "rustfmt", "--"]);
|
||||||
|
cmd
|
||||||
|
} else {
|
||||||
|
Command::new(rustfmt)
|
||||||
|
};
|
||||||
|
|
||||||
|
cmd
|
||||||
|
.args(&["--write-mode=display"])
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped());
|
||||||
|
|
||||||
if let Some(path) = self.options
|
if let Some(path) = self.options
|
||||||
.rustfmt_configuration_file
|
.rustfmt_configuration_file
|
||||||
@ -1710,34 +1726,52 @@ impl Bindings {
|
|||||||
cmd.args(&["--config-path", path]);
|
cmd.args(&["--config-path", path]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(output) = cmd.arg(file).output() {
|
match cmd.spawn() {
|
||||||
if !output.status.success() {
|
Ok(mut child) => {
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
let mut child_stdin = child.stdin.take().unwrap();
|
||||||
match output.status.code() {
|
let mut child_stdout = child.stdout.take().unwrap();
|
||||||
Some(2) => Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
// Write to stdin in a new thread, so that we can read from stdout on this
|
||||||
format!("Rustfmt parsing errors:\n{}", stderr),
|
// thread. This keeps the child from blocking on writing to its stdout which
|
||||||
)),
|
// might block us from writing to its stdin.
|
||||||
Some(3) => {
|
let stdin_handle = ::std::thread::spawn(move || {
|
||||||
warn!(
|
let _ = child_stdin.write_all(source.as_bytes());
|
||||||
"Rustfmt could not format some lines:\n{}",
|
source
|
||||||
stderr
|
});
|
||||||
);
|
|
||||||
Ok(())
|
let mut output = vec![];
|
||||||
}
|
io::copy(&mut child_stdout, &mut output)?;
|
||||||
_ => Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
let status = child.wait()?;
|
||||||
format!("Internal rustfmt error:\n{}", stderr),
|
let source = stdin_handle.join()
|
||||||
)),
|
.expect("The thread writing to rustfmt's stdin doesn't do \
|
||||||
|
anything that could panic");
|
||||||
|
|
||||||
|
match String::from_utf8(output) {
|
||||||
|
Ok(bindings) => {
|
||||||
|
match status.code() {
|
||||||
|
Some(0) => Ok(bindings),
|
||||||
|
Some(2) => Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"Rustfmt parsing errors.".to_string(),
|
||||||
|
)),
|
||||||
|
Some(3) => {
|
||||||
|
warn!("Rustfmt could not format some lines.");
|
||||||
|
Ok(bindings)
|
||||||
|
}
|
||||||
|
_ => Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"Internal rustfmt error".to_string(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => Ok(source)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
} else {
|
Err(e) => {
|
||||||
Err(io::Error::new(
|
eprintln!("Error spawning rustfmt: {}", e);
|
||||||
io::ErrorKind::Other,
|
Ok(source)
|
||||||
"Error executing rustfmt!",
|
}
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,6 +256,9 @@ fn create_bindgen_builder(header: &PathBuf) -> Result<Option<Builder>, Error> {
|
|||||||
|
|
||||||
let prepend = [
|
let prepend = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
|
// We format in `compare_generated_header` ourselves to have a little
|
||||||
|
// more control.
|
||||||
|
"--no-rustfmt-bindings",
|
||||||
"--with-derive-default",
|
"--with-derive-default",
|
||||||
header_str,
|
header_str,
|
||||||
"--raw-line",
|
"--raw-line",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user