@@ -80,6 +80,7 @@ use ir::item::Item;
80
80
use parse:: { ClangItemParser , ParseError } ;
81
81
use regex_set:: RegexSet ;
82
82
83
+ use std:: borrow:: Cow ;
83
84
use std:: fs:: { File , OpenOptions } ;
84
85
use std:: io:: { self , Write } ;
85
86
use std:: iter;
@@ -1678,30 +1679,32 @@ impl Bindings {
1678
1679
1679
1680
let bindings = self . module . as_str ( ) . to_string ( ) ;
1680
1681
1681
- match self . rustfmt_generated_string ( bindings) {
1682
+ match self . rustfmt_generated_string ( & bindings) {
1682
1683
Ok ( rustfmt_bindings) => {
1683
- writer. write ( rustfmt_bindings. as_str ( ) . as_bytes ( ) ) ?;
1684
+ writer. write ( rustfmt_bindings. as_bytes ( ) ) ?;
1685
+ } ,
1686
+ Err ( err) => {
1687
+ eprintln ! ( "{:?}" , err) ;
1688
+ writer. write ( bindings. as_str ( ) . as_bytes ( ) ) ?;
1684
1689
} ,
1685
- Err ( err) => eprintln ! ( "{:?}" , err) ,
1686
1690
}
1687
1691
Ok ( ( ) )
1688
1692
}
1689
1693
1690
1694
/// Checks if rustfmt_bindings is set and runs rustfmt on the string
1691
- fn rustfmt_generated_string ( & self , source : String ) -> io:: Result < String > {
1695
+ fn rustfmt_generated_string < ' a > (
1696
+ & self ,
1697
+ source : & ' a str ,
1698
+ ) -> io:: Result < Cow < ' a , str > > {
1692
1699
let _t = time:: Timer :: new ( "rustfmt_generated_string" )
1693
1700
. with_output ( self . options . time_phases ) ;
1694
1701
1695
1702
if !self . options . rustfmt_bindings {
1696
- return Ok ( source) ;
1703
+ return Ok ( Cow :: Borrowed ( source) ) ;
1697
1704
}
1698
1705
1699
- let rustfmt = if let Ok ( rustfmt) = which:: which ( "rustfmt" ) {
1700
- rustfmt
1701
- } else {
1702
- eprintln ! ( "warning: could not find usable rustfmt to pretty print bindings" ) ;
1703
- return Ok ( source) ;
1704
- } ;
1706
+ let rustfmt = which:: which ( "rustfmt" )
1707
+ . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e. to_owned ( ) ) ) ?;
1705
1708
1706
1709
// Prefer using the `rustfmt-nightly` version of `rustmft`, if
1707
1710
// possible. It requires being run via `rustup run nightly ...`.
@@ -1726,52 +1729,47 @@ impl Bindings {
1726
1729
cmd. args ( & [ "--config-path" , path] ) ;
1727
1730
}
1728
1731
1729
- match cmd. spawn ( ) {
1730
- Ok ( mut child) => {
1731
- let mut child_stdin = child. stdin . take ( ) . unwrap ( ) ;
1732
- let mut child_stdout = child. stdout . take ( ) . unwrap ( ) ;
1733
-
1734
- // Write to stdin in a new thread, so that we can read from stdout on this
1735
- // thread. This keeps the child from blocking on writing to its stdout which
1736
- // might block us from writing to its stdin.
1737
- let stdin_handle = :: std:: thread:: spawn ( move || {
1738
- let _ = child_stdin. write_all ( source. as_bytes ( ) ) ;
1739
- source
1740
- } ) ;
1741
-
1742
- let mut output = vec ! [ ] ;
1743
- io:: copy ( & mut child_stdout, & mut output) ?;
1744
-
1745
- let status = child. wait ( ) ?;
1746
- let source = stdin_handle. join ( )
1747
- . expect ( "The thread writing to rustfmt's stdin doesn't do \
1748
- anything that could panic") ;
1749
-
1750
- match String :: from_utf8 ( output) {
1751
- Ok ( bindings) => {
1752
- match status. code ( ) {
1753
- Some ( 0 ) => Ok ( bindings) ,
1754
- Some ( 2 ) => Err ( io:: Error :: new (
1755
- io:: ErrorKind :: Other ,
1756
- "Rustfmt parsing errors." . to_string ( ) ,
1757
- ) ) ,
1758
- Some ( 3 ) => {
1759
- warn ! ( "Rustfmt could not format some lines." ) ;
1760
- Ok ( bindings)
1761
- }
1762
- _ => Err ( io:: Error :: new (
1763
- io:: ErrorKind :: Other ,
1764
- "Internal rustfmt error" . to_string ( ) ,
1765
- ) ) ,
1766
- }
1767
- } ,
1768
- _ => Ok ( source)
1732
+ let mut child = cmd. spawn ( ) ?;
1733
+ let mut child_stdin = child. stdin . take ( ) . unwrap ( ) ;
1734
+ let mut child_stdout = child. stdout . take ( ) . unwrap ( ) ;
1735
+
1736
+ let source = source. to_owned ( ) ;
1737
+
1738
+ // Write to stdin in a new thread, so that we can read from stdout on this
1739
+ // thread. This keeps the child from blocking on writing to its stdout which
1740
+ // might block us from writing to its stdin.
1741
+ let stdin_handle = :: std:: thread:: spawn ( move || {
1742
+ let _ = child_stdin. write_all ( source. as_bytes ( ) ) ;
1743
+ source
1744
+ } ) ;
1745
+
1746
+ let mut output = vec ! [ ] ;
1747
+ io:: copy ( & mut child_stdout, & mut output) ?;
1748
+
1749
+ let status = child. wait ( ) ?;
1750
+ let source = stdin_handle. join ( )
1751
+ . expect ( "The thread writing to rustfmt's stdin doesn't do \
1752
+ anything that could panic") ;
1753
+
1754
+ match String :: from_utf8 ( output) {
1755
+ Ok ( bindings) => {
1756
+ match status. code ( ) {
1757
+ Some ( 0 ) => Ok ( Cow :: Owned ( bindings) ) ,
1758
+ Some ( 2 ) => Err ( io:: Error :: new (
1759
+ io:: ErrorKind :: Other ,
1760
+ "Rustfmt parsing errors." . to_string ( ) ,
1761
+ ) ) ,
1762
+ Some ( 3 ) => {
1763
+ warn ! ( "Rustfmt could not format some lines." ) ;
1764
+ Ok ( Cow :: Owned ( bindings) )
1765
+ }
1766
+ _ => Err ( io:: Error :: new (
1767
+ io:: ErrorKind :: Other ,
1768
+ "Internal rustfmt error" . to_string ( ) ,
1769
+ ) ) ,
1769
1770
}
1770
- }
1771
- Err ( e) => {
1772
- eprintln ! ( "Error spawning rustfmt: {}" , e) ;
1773
- Ok ( source)
1774
- }
1771
+ } ,
1772
+ _ => Ok ( Cow :: Owned ( source) )
1775
1773
}
1776
1774
}
1777
1775
}
0 commit comments