@@ -1580,18 +1580,15 @@ impl Bindings {
1580
1580
1581
1581
/// Write these bindings as source text to a file.
1582
1582
pub fn write_to_file < P : AsRef < Path > > ( & self , path : P ) -> io:: Result < ( ) > {
1583
- {
1584
- let file = try!(
1585
- OpenOptions :: new ( )
1586
- . write ( true )
1587
- . truncate ( true )
1588
- . create ( true )
1589
- . open ( path. as_ref ( ) )
1590
- ) ;
1591
- self . write ( Box :: new ( file) ) ?;
1592
- }
1593
-
1594
- self . rustfmt_generated_file ( path. as_ref ( ) )
1583
+ let file = try!(
1584
+ OpenOptions :: new ( )
1585
+ . write ( true )
1586
+ . truncate ( true )
1587
+ . create ( true )
1588
+ . open ( path. as_ref ( ) )
1589
+ ) ;
1590
+ self . write ( Box :: new ( file) ) ?;
1591
+ Ok ( ( ) )
1595
1592
}
1596
1593
1597
1594
/// Write these bindings as source text to the given `Write`able.
@@ -1604,11 +1601,19 @@ impl Bindings {
1604
1601
writer. write ( line. as_bytes ( ) ) ?;
1605
1602
writer. write ( "\n " . as_bytes ( ) ) ?;
1606
1603
}
1604
+
1607
1605
if !self . options . raw_lines . is_empty ( ) {
1608
1606
writer. write ( "\n " . as_bytes ( ) ) ?;
1609
1607
}
1610
1608
1611
- writer. write ( self . module . as_str ( ) . as_bytes ( ) ) ?;
1609
+ let bindings = self . module . as_str ( ) . to_string ( ) ;
1610
+
1611
+ match self . rustfmt_generated_string ( bindings) {
1612
+ Ok ( rustfmt_bindings) => {
1613
+ writer. write ( rustfmt_bindings. as_str ( ) . as_bytes ( ) ) ?;
1614
+ } ,
1615
+ Err ( err) => eprintln ! ( "{:?}" , err) ,
1616
+ }
1612
1617
Ok ( ( ) )
1613
1618
}
1614
1619
@@ -1668,6 +1673,79 @@ impl Bindings {
1668
1673
) )
1669
1674
}
1670
1675
}
1676
+
1677
+ /// Checks if rustfmt_bindings is set and runs rustfmt on the string
1678
+ //fn rustfmt_generated_string(&self, source: String) -> io::Result<Option<(String, String)>> {
1679
+ fn rustfmt_generated_string ( & self , source : String ) -> io:: Result < String > {
1680
+ let _t = self . context . timer ( "rustfmt_generated_string" ) ;
1681
+
1682
+ if !self . context . options ( ) . rustfmt_bindings {
1683
+ return Ok ( source) ;
1684
+ }
1685
+
1686
+ let rustfmt = if let Ok ( rustfmt) = which:: which ( "rustfmt" ) {
1687
+ rustfmt
1688
+ } else {
1689
+ eprintln ! ( "warning: could not find usable rustfmt to pretty print bindings" ) ;
1690
+ return Ok ( source) ;
1691
+ } ;
1692
+
1693
+ let mut cmd = if let Ok ( rustup) = which:: which ( "rustup" ) {
1694
+ let mut cmd = Command :: new ( rustup) ;
1695
+ cmd. args ( & [ "run" , "nightly" , "rustfmt" , "--" ] ) ;
1696
+ cmd
1697
+ } else {
1698
+ Command :: new ( rustfmt)
1699
+ } ;
1700
+
1701
+ cmd
1702
+ . args ( & [ "--write-mode=display" ] )
1703
+ . stdin ( Stdio :: piped ( ) )
1704
+ . stdout ( Stdio :: piped ( ) )
1705
+ . stderr ( Stdio :: piped ( ) ) ;
1706
+
1707
+ if let Some ( path) = self . context
1708
+ . options ( )
1709
+ . rustfmt_configuration_file
1710
+ . as_ref ( )
1711
+ . and_then ( |f| f. to_str ( ) )
1712
+ {
1713
+ cmd. args ( & [ "--config-path" , path] ) ;
1714
+ }
1715
+
1716
+ let mut child = cmd. spawn ( ) . expect ( "Failed to spawn rustfmt." ) ;
1717
+ let mut child_stdin = child. stdin . take ( ) . unwrap ( ) ;
1718
+ let mut child_stdout = child. stdout . take ( ) . unwrap ( ) ;
1719
+ let mut child_stderr = child. stderr . take ( ) . unwrap ( ) ;
1720
+
1721
+ // Write to stdin in a new thread, so that we can read from stdout on this
1722
+ // thread. This keeps the child from blocking on writing to its stdout which
1723
+ // might block us from writing to its stdin.
1724
+ let stdin_handle = :: std:: thread:: spawn ( move || {
1725
+ child_stdin. write_all ( source. as_bytes ( ) )
1726
+ } ) ;
1727
+
1728
+ // Read stderr on a new thread for similar reasons.
1729
+ let stderr_handle = :: std:: thread:: spawn ( move || {
1730
+ let mut output = vec ! [ ] ;
1731
+ io:: copy ( & mut child_stderr, & mut output)
1732
+ . map ( |_| String :: from_utf8_lossy ( & output) . to_string ( ) )
1733
+ } ) ;
1734
+
1735
+ let mut output = vec ! [ ] ;
1736
+ io:: copy ( & mut child_stdout, & mut output)
1737
+ . expect ( "Should copy stdout into vec OK" ) ;
1738
+
1739
+ // Ignore actual rustfmt status because it is often non-zero for trivial
1740
+ // things.
1741
+ let _ = child. wait ( ) . expect ( "should wait on rustfmt child OK" ) ;
1742
+
1743
+ stdin_handle. join ( ) ;
1744
+ let bindings = String :: from_utf8 ( output) . unwrap ( ) ;
1745
+ let child_stderr = stderr_handle. join ( ) ;
1746
+
1747
+ Ok ( bindings)
1748
+ }
1671
1749
}
1672
1750
1673
1751
/// Determines whether the given cursor is in any of the files matched by the
0 commit comments