@@ -39,7 +39,8 @@ use std::cell::RefCell;
39
39
use std:: cmp:: Ordering ;
40
40
use std:: collections:: { BTreeMap , HashMap , HashSet } ;
41
41
use std:: default:: Default ;
42
- use std:: fmt;
42
+ use std:: error;
43
+ use std:: fmt:: { self , Display , Formatter } ;
43
44
use std:: fs:: { self , File } ;
44
45
use std:: io:: prelude:: * ;
45
46
use std:: io:: { self , BufWriter , BufReader } ;
@@ -144,6 +145,42 @@ impl Impl {
144
145
}
145
146
}
146
147
148
+ #[ derive( Debug ) ]
149
+ pub struct Error {
150
+ file : PathBuf ,
151
+ error : io:: Error ,
152
+ }
153
+
154
+ impl error:: Error for Error {
155
+ fn description ( & self ) -> & str {
156
+ self . error . description ( )
157
+ }
158
+ }
159
+
160
+ impl Display for Error {
161
+ fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
162
+ write ! ( f, "\" {}\" : {}" , self . file. display( ) , self . error)
163
+ }
164
+ }
165
+
166
+ impl Error {
167
+ pub fn new ( e : io:: Error , file : & Path ) -> Error {
168
+ Error {
169
+ file : file. to_path_buf ( ) ,
170
+ error : e,
171
+ }
172
+ }
173
+ }
174
+
175
+ macro_rules! try_err {
176
+ ( $e: expr, $file: expr) => ( {
177
+ match $e {
178
+ Ok ( e) => e,
179
+ Err ( e) => return Err ( Error :: new( e, $file) ) ,
180
+ }
181
+ } )
182
+ }
183
+
147
184
/// This cache is used to store information about the `clean::Crate` being
148
185
/// rendered in order to provide more useful documentation. This contains
149
186
/// information like all implementors of a trait, all traits a type implements,
@@ -309,7 +346,7 @@ thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> =
309
346
pub fn run ( mut krate : clean:: Crate ,
310
347
external_html : & ExternalHtml ,
311
348
dst : PathBuf ,
312
- passes : HashSet < String > ) -> io :: Result < ( ) > {
349
+ passes : HashSet < String > ) -> Result < ( ) , Error > {
313
350
let src_root = match krate. src . parent ( ) {
314
351
Some ( p) => p. to_path_buf ( ) ,
315
352
None => PathBuf :: new ( ) ,
@@ -332,7 +369,7 @@ pub fn run(mut krate: clean::Crate,
332
369
issue_tracker_base_url : None ,
333
370
} ;
334
371
335
- try !( mkdir ( & cx. dst ) ) ;
372
+ try_err ! ( mkdir( & cx. dst) , & cx . dst ) ;
336
373
337
374
// Crawl the crate attributes looking for attributes which control how we're
338
375
// going to emit HTML
@@ -434,7 +471,7 @@ pub fn run(mut krate: clean::Crate,
434
471
krate = cache. fold_crate ( krate) ;
435
472
436
473
// Build our search index
437
- let index = try! ( build_index ( & krate, & mut cache) ) ;
474
+ let index = build_index ( & krate, & mut cache) ;
438
475
439
476
// Freeze the cache now that the index has been built. Put an Arc into TLS
440
477
// for future parallelization opportunities
@@ -449,7 +486,7 @@ pub fn run(mut krate: clean::Crate,
449
486
cx. krate ( krate)
450
487
}
451
488
452
- fn build_index ( krate : & clean:: Crate , cache : & mut Cache ) -> io :: Result < String > {
489
+ fn build_index ( krate : & clean:: Crate , cache : & mut Cache ) -> String {
453
490
// Build the search index from the collected metadata
454
491
let mut nodeid_to_pathid = HashMap :: new ( ) ;
455
492
let mut pathid_to_nodeid = Vec :: new ( ) ;
@@ -476,7 +513,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
476
513
} ,
477
514
None => { }
478
515
}
479
- } ;
516
+ }
480
517
481
518
// Reduce `NodeId` in paths into smaller sequential numbers,
482
519
// and prune the paths that do not appear in the index.
@@ -497,7 +534,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
497
534
498
535
// Collect the index into a string
499
536
let mut w = io:: Cursor :: new ( Vec :: new ( ) ) ;
500
- try! ( write ! ( & mut w, r#"searchIndex['{}'] = {{"items":["# , krate. name) ) ;
537
+ write ! ( & mut w, r#"searchIndex['{}'] = {{"items":["# , krate. name) . unwrap ( ) ;
501
538
502
539
let mut lastpath = "" . to_string ( ) ;
503
540
for ( i, item) in cache. search_index . iter ( ) . enumerate ( ) {
@@ -511,58 +548,61 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
511
548
} ;
512
549
513
550
if i > 0 {
514
- try! ( write ! ( & mut w, "," ) ) ;
551
+ write ! ( & mut w, "," ) . unwrap ( ) ;
515
552
}
516
- try! ( write ! ( & mut w, r#"[{},"{}","{}",{}"# ,
517
- item. ty as usize , item. name, path,
518
- item. desc. to_json( ) . to_string( ) ) ) ;
553
+ write ! ( & mut w, r#"[{},"{}","{}",{}"# ,
554
+ item. ty as usize , item. name, path,
555
+ item. desc. to_json( ) . to_string( ) ) . unwrap ( ) ;
519
556
match item. parent {
520
557
Some ( nodeid) => {
521
558
let pathid = * nodeid_to_pathid. get ( & nodeid) . unwrap ( ) ;
522
- try! ( write ! ( & mut w, ",{}" , pathid) ) ;
559
+ write ! ( & mut w, ",{}" , pathid) . unwrap ( ) ;
523
560
}
524
- None => try! ( write ! ( & mut w, ",null" ) )
561
+ None => write ! ( & mut w, ",null" ) . unwrap ( )
525
562
}
526
563
match item. search_type {
527
- Some ( ref t) => try! ( write ! ( & mut w, ",{}" , t) ) ,
528
- None => try! ( write ! ( & mut w, ",null" ) )
564
+ Some ( ref t) => write ! ( & mut w, ",{}" , t) . unwrap ( ) ,
565
+ None => write ! ( & mut w, ",null" ) . unwrap ( )
529
566
}
530
- try! ( write ! ( & mut w, "]" ) ) ;
567
+ write ! ( & mut w, "]" ) . unwrap ( ) ;
531
568
}
532
569
533
- try! ( write ! ( & mut w, r#"],"paths":["# ) ) ;
570
+ write ! ( & mut w, r#"],"paths":["# ) . unwrap ( ) ;
534
571
535
572
for ( i, & did) in pathid_to_nodeid. iter ( ) . enumerate ( ) {
536
573
let & ( ref fqp, short) = cache. paths . get ( & did) . unwrap ( ) ;
537
574
if i > 0 {
538
- try! ( write ! ( & mut w, "," ) ) ;
575
+ write ! ( & mut w, "," ) . unwrap ( ) ;
539
576
}
540
- try! ( write ! ( & mut w, r#"[{},"{}"]"# ,
541
- short as usize , * fqp. last( ) . unwrap( ) ) ) ;
577
+ write ! ( & mut w, r#"[{},"{}"]"# ,
578
+ short as usize , * fqp. last( ) . unwrap( ) ) . unwrap ( ) ;
542
579
}
543
580
544
- try! ( write ! ( & mut w, "]}};" ) ) ;
581
+ write ! ( & mut w, "]}};" ) . unwrap ( ) ;
545
582
546
- Ok ( String :: from_utf8 ( w. into_inner ( ) ) . unwrap ( ) )
583
+ String :: from_utf8 ( w. into_inner ( ) ) . unwrap ( )
547
584
}
548
585
549
586
fn write_shared ( cx : & Context ,
550
587
krate : & clean:: Crate ,
551
588
cache : & Cache ,
552
- search_index : String ) -> io :: Result < ( ) > {
589
+ search_index : String ) -> Result < ( ) , Error > {
553
590
// Write out the shared files. Note that these are shared among all rustdoc
554
591
// docs placed in the output directory, so this needs to be a synchronized
555
592
// operation with respect to all other rustdocs running around.
556
- try !( mkdir ( & cx. dst ) ) ;
593
+ try_err ! ( mkdir( & cx. dst) , & cx . dst ) ;
557
594
let _lock = :: flock:: Lock :: new ( & cx. dst . join ( ".lock" ) ) ;
558
595
559
596
// Add all the static files. These may already exist, but we just
560
597
// overwrite them anyway to make sure that they're fresh and up-to-date.
561
598
try!( write ( cx. dst . join ( "jquery.js" ) ,
562
599
include_bytes ! ( "static/jquery-2.1.4.min.js" ) ) ) ;
563
- try!( write ( cx. dst . join ( "main.js" ) , include_bytes ! ( "static/main.js" ) ) ) ;
564
- try!( write ( cx. dst . join ( "playpen.js" ) , include_bytes ! ( "static/playpen.js" ) ) ) ;
565
- try!( write ( cx. dst . join ( "main.css" ) , include_bytes ! ( "static/main.css" ) ) ) ;
600
+ try!( write ( cx. dst . join ( "main.js" ) ,
601
+ include_bytes ! ( "static/main.js" ) ) ) ;
602
+ try!( write ( cx. dst . join ( "playpen.js" ) ,
603
+ include_bytes ! ( "static/playpen.js" ) ) ) ;
604
+ try!( write ( cx. dst . join ( "main.css" ) ,
605
+ include_bytes ! ( "static/main.css" ) ) ) ;
566
606
try!( write ( cx. dst . join ( "normalize.css" ) ,
567
607
include_bytes ! ( "static/normalize.css" ) ) ) ;
568
608
try!( write ( cx. dst . join ( "FiraSans-Regular.woff" ) ,
@@ -614,18 +654,18 @@ fn write_shared(cx: &Context,
614
654
615
655
// Update the search index
616
656
let dst = cx. dst . join ( "search-index.js" ) ;
617
- let all_indexes = try !( collect ( & dst, & krate. name , "searchIndex" ) ) ;
618
- let mut w = try !( File :: create ( & dst) ) ;
619
- try !( writeln ! ( & mut w, "var searchIndex = {{}};" ) ) ;
620
- try !( writeln ! ( & mut w, "{}" , search_index) ) ;
657
+ let all_indexes = try_err ! ( collect( & dst, & krate. name, "searchIndex" ) , & dst ) ;
658
+ let mut w = try_err ! ( File :: create( & dst) , & dst ) ;
659
+ try_err ! ( writeln!( & mut w, "var searchIndex = {{}};" ) , & dst ) ;
660
+ try_err ! ( writeln!( & mut w, "{}" , search_index) , & dst ) ;
621
661
for index in & all_indexes {
622
- try !( writeln ! ( & mut w, "{}" , * index) ) ;
662
+ try_err ! ( writeln!( & mut w, "{}" , * index) , & dst ) ;
623
663
}
624
- try !( writeln ! ( & mut w, "initSearch(searchIndex);" ) ) ;
664
+ try_err ! ( writeln!( & mut w, "initSearch(searchIndex);" ) , & dst ) ;
625
665
626
666
// Update the list of all implementors for traits
627
667
let dst = cx. dst . join ( "implementors" ) ;
628
- try !( mkdir ( & dst) ) ;
668
+ try_err ! ( mkdir( & dst) , & dst ) ;
629
669
for ( & did, imps) in & cache. implementors {
630
670
// Private modules can leak through to this phase of rustdoc, which
631
671
// could contain implementations for otherwise private types. In some
@@ -642,51 +682,53 @@ fn write_shared(cx: &Context,
642
682
let mut mydst = dst. clone ( ) ;
643
683
for part in & remote_path[ ..remote_path. len ( ) - 1 ] {
644
684
mydst. push ( part) ;
645
- try !( mkdir ( & mydst) ) ;
685
+ try_err ! ( mkdir( & mydst) , & mydst ) ;
646
686
}
647
687
mydst. push ( & format ! ( "{}.{}.js" ,
648
688
remote_item_type. to_static_str( ) ,
649
689
remote_path[ remote_path. len( ) - 1 ] ) ) ;
650
- let all_implementors = try!( collect ( & mydst, & krate. name ,
651
- "implementors" ) ) ;
690
+ let all_implementors = try_err ! ( collect( & mydst, & krate. name,
691
+ "implementors" ) ,
692
+ & mydst) ;
652
693
653
- try!( mkdir ( mydst. parent ( ) . unwrap ( ) ) ) ;
654
- let mut f = BufWriter :: new ( try!( File :: create ( & mydst) ) ) ;
655
- try!( writeln ! ( & mut f, "(function() {{var implementors = {{}};" ) ) ;
694
+ try_err ! ( mkdir( mydst. parent( ) . unwrap( ) ) ,
695
+ & mydst. parent( ) . unwrap( ) . to_path_buf( ) ) ;
696
+ let mut f = BufWriter :: new ( try_err ! ( File :: create( & mydst) , & mydst) ) ;
697
+ try_err ! ( writeln!( & mut f, "(function() {{var implementors = {{}};" ) , & mydst) ;
656
698
657
699
for implementor in & all_implementors {
658
- try !( write ! ( & mut f, "{}" , * implementor) ) ;
700
+ try_err ! ( write!( & mut f, "{}" , * implementor) , & mydst ) ;
659
701
}
660
702
661
- try !( write ! ( & mut f, r"implementors['{}'] = [" , krate. name) ) ;
703
+ try_err ! ( write!( & mut f, r"implementors['{}'] = [" , krate. name) , & mydst ) ;
662
704
for imp in imps {
663
705
// If the trait and implementation are in the same crate, then
664
706
// there's no need to emit information about it (there's inlining
665
707
// going on). If they're in different crates then the crate defining
666
708
// the trait will be interested in our implementation.
667
709
if imp. def_id . krate == did. krate { continue }
668
- try !( write ! ( & mut f, r#""{}","# , imp. impl_) ) ;
710
+ try_err ! ( write!( & mut f, r#""{}","# , imp. impl_) , & mydst ) ;
669
711
}
670
- try !( writeln ! ( & mut f, r"];" ) ) ;
671
- try !( writeln ! ( & mut f, "{}" , r"
712
+ try_err ! ( writeln!( & mut f, r"];" ) , & mydst ) ;
713
+ try_err ! ( writeln!( & mut f, "{}" , r"
672
714
if (window.register_implementors) {
673
715
window.register_implementors(implementors);
674
716
} else {
675
717
window.pending_implementors = implementors;
676
718
}
677
- " ) ) ;
678
- try !( writeln ! ( & mut f, r"}})()" ) ) ;
719
+ " ) , & mydst ) ;
720
+ try_err ! ( writeln!( & mut f, r"}})()" ) , & mydst ) ;
679
721
}
680
722
Ok ( ( ) )
681
723
}
682
724
683
725
fn render_sources ( cx : & mut Context ,
684
- krate : clean:: Crate ) -> io :: Result < clean:: Crate > {
726
+ krate : clean:: Crate ) -> Result < clean:: Crate , Error > {
685
727
info ! ( "emitting source files" ) ;
686
728
let dst = cx. dst . join ( "src" ) ;
687
- try !( mkdir ( & dst) ) ;
729
+ try_err ! ( mkdir( & dst) , & dst ) ;
688
730
let dst = dst. join ( & krate. name ) ;
689
- try !( mkdir ( & dst) ) ;
731
+ try_err ! ( mkdir( & dst) , & dst ) ;
690
732
let mut folder = SourceCollector {
691
733
dst : dst,
692
734
seen : HashSet :: new ( ) ,
@@ -699,8 +741,8 @@ fn render_sources(cx: &mut Context,
699
741
700
742
/// Writes the entire contents of a string to a destination, not attempting to
701
743
/// catch any errors.
702
- fn write ( dst : PathBuf , contents : & [ u8 ] ) -> io :: Result < ( ) > {
703
- try! ( File :: create ( & dst) ) . write_all ( contents)
744
+ fn write ( dst : PathBuf , contents : & [ u8 ] ) -> Result < ( ) , Error > {
745
+ Ok ( try_err ! ( try_err! ( File :: create( & dst) , & dst ) . write_all( contents) , & dst ) )
704
746
}
705
747
706
748
/// Makes a directory on the filesystem, failing the thread if an error occurs and
@@ -849,7 +891,6 @@ impl<'a> SourceCollector<'a> {
849
891
fname. push ( ".html" ) ;
850
892
cur. push ( & fname[ ..] ) ;
851
893
let mut w = BufWriter :: new ( try!( File :: create ( & cur) ) ) ;
852
-
853
894
let title = format ! ( "{} -- source" , cur. file_name( ) . unwrap( )
854
895
. to_string_lossy( ) ) ;
855
896
let desc = format ! ( "Source to the Rust file `{}`." , filename) ;
@@ -1166,7 +1207,7 @@ impl Context {
1166
1207
///
1167
1208
/// This currently isn't parallelized, but it'd be pretty easy to add
1168
1209
/// parallelization to this function.
1169
- fn krate ( self , mut krate : clean:: Crate ) -> io :: Result < ( ) > {
1210
+ fn krate ( self , mut krate : clean:: Crate ) -> Result < ( ) , Error > {
1170
1211
let mut item = match krate. module . take ( ) {
1171
1212
Some ( i) => i,
1172
1213
None => return Ok ( ( ) )
@@ -1192,7 +1233,7 @@ impl Context {
1192
1233
/// all sub-items which need to be rendered.
1193
1234
///
1194
1235
/// The rendering driver uses this closure to queue up more work.
1195
- fn item < F > ( & mut self , item : clean:: Item , mut f : F ) -> io :: Result < ( ) > where
1236
+ fn item < F > ( & mut self , item : clean:: Item , mut f : F ) -> Result < ( ) , Error > where
1196
1237
F : FnMut ( & mut Context , clean:: Item ) ,
1197
1238
{
1198
1239
fn render ( w : File , cx : & Context , it : & clean:: Item ,
@@ -1279,9 +1320,9 @@ impl Context {
1279
1320
let mut item = Some ( item) ;
1280
1321
self . recurse ( name, |this| {
1281
1322
let item = item. take ( ) . unwrap ( ) ;
1282
- let dst = this. dst . join ( "index.html" ) ;
1283
- let dst = try !( File :: create ( & dst ) ) ;
1284
- try !( render ( dst, this, & item, false ) ) ;
1323
+ let joint_dst = this. dst . join ( "index.html" ) ;
1324
+ let dst = try_err ! ( File :: create( & joint_dst ) , & joint_dst ) ;
1325
+ try_err ! ( render( dst, this, & item, false ) , & joint_dst ) ;
1285
1326
1286
1327
let m = match item. inner {
1287
1328
clean:: ModuleItem ( m) => m,
@@ -1292,9 +1333,9 @@ impl Context {
1292
1333
{
1293
1334
let items = this. build_sidebar_items ( & m) ;
1294
1335
let js_dst = this. dst . join ( "sidebar-items.js" ) ;
1295
- let mut js_out = BufWriter :: new ( try !( File :: create ( & js_dst) ) ) ;
1296
- try !( write ! ( & mut js_out, "initSidebarItems({});" ,
1297
- json:: as_json( & items) ) ) ;
1336
+ let mut js_out = BufWriter :: new ( try_err ! ( File :: create( & js_dst) , & js_dst ) ) ;
1337
+ try_err ! ( write!( & mut js_out, "initSidebarItems({});" ,
1338
+ json:: as_json( & items) ) , & js_dst ) ;
1298
1339
}
1299
1340
1300
1341
for item in m. items {
@@ -1307,9 +1348,11 @@ impl Context {
1307
1348
// Things which don't have names (like impls) don't get special
1308
1349
// pages dedicated to them.
1309
1350
_ if item. name . is_some ( ) => {
1310
- let dst = self . dst . join ( & item_path ( & item) ) ;
1311
- let dst = try!( File :: create ( & dst) ) ;
1312
- render ( dst, self , & item, true )
1351
+ let joint_dst = self . dst . join ( & item_path ( & item) ) ;
1352
+
1353
+ let dst = try_err ! ( File :: create( & joint_dst) , & joint_dst) ;
1354
+ try_err ! ( render( dst, self , & item, true ) , & joint_dst) ;
1355
+ Ok ( ( ) )
1313
1356
}
1314
1357
1315
1358
_ => Ok ( ( ) )
0 commit comments