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