@@ -91,12 +91,20 @@ pub struct Context {
9191 /// String representation of how to get back to the root path of the 'doc/'
9292 /// folder in terms of a relative URL.
9393 pub root_path : String ,
94- /// The path to the crate root source minus the file name.
95- /// Used for simplifying paths to the highlighted source code files.
96- pub src_root : PathBuf ,
9794 /// The current destination folder of where HTML artifacts should be placed.
9895 /// This changes as the context descends into the module hierarchy.
9996 pub dst : PathBuf ,
97+ /// A flag, which when `true`, will render pages which redirect to the
98+ /// real location of an item. This is used to allow external links to
99+ /// publicly reused items to redirect to the right location.
100+ pub render_redirect_pages : bool ,
101+ pub shared : Arc < SharedContext > ,
102+ }
103+
104+ pub struct SharedContext {
105+ /// The path to the crate root source minus the file name.
106+ /// Used for simplifying paths to the highlighted source code files.
107+ pub src_root : PathBuf ,
100108 /// This describes the layout of each page, and is not modified after
101109 /// creation of the context (contains info like the favicon and added html).
102110 pub layout : layout:: Layout ,
@@ -106,10 +114,6 @@ pub struct Context {
106114 pub include_sources : bool ,
107115 /// The local file sources we've emitted and their respective url-paths.
108116 pub local_sources : HashMap < PathBuf , String > ,
109- /// A flag, which when turned off, will render pages which redirect to the
110- /// real location of an item. This is used to allow external links to
111- /// publicly reused items to redirect to the right location.
112- pub render_redirect_pages : bool ,
113117 /// All the passes that were run on this crate.
114118 pub passes : HashSet < String > ,
115119 /// The base-URL of the issue tracker for when an item has been tagged with
@@ -259,7 +263,7 @@ pub struct Cache {
259263
260264/// Helper struct to render all source code to HTML pages
261265struct SourceCollector < ' a > {
262- cx : & ' a mut Context ,
266+ scx : & ' a mut SharedContext ,
263267
264268 /// Root destination to place all HTML output into
265269 dst : PathBuf ,
@@ -412,43 +416,37 @@ pub fn run(mut krate: clean::Crate,
412416 Some ( p) => p. to_path_buf ( ) ,
413417 None => PathBuf :: new ( ) ,
414418 } ;
415- let mut cx = Context {
416- dst : dst,
419+ let mut scx = SharedContext {
417420 src_root : src_root,
418421 passes : passes,
419- current : Vec :: new ( ) ,
420- root_path : String :: new ( ) ,
422+ include_sources : true ,
423+ local_sources : HashMap :: new ( ) ,
424+ issue_tracker_base_url : None ,
421425 layout : layout:: Layout {
422426 logo : "" . to_string ( ) ,
423427 favicon : "" . to_string ( ) ,
424428 external_html : external_html. clone ( ) ,
425429 krate : krate. name . clone ( ) ,
426430 playground_url : "" . to_string ( ) ,
427431 } ,
428- include_sources : true ,
429- local_sources : HashMap :: new ( ) ,
430- render_redirect_pages : false ,
431- issue_tracker_base_url : None ,
432432 } ;
433433
434- try_err ! ( mkdir( & cx. dst) , & cx. dst) ;
435-
436434 // Crawl the crate attributes looking for attributes which control how we're
437435 // going to emit HTML
438436 if let Some ( attrs) = krate. module . as_ref ( ) . map ( |m| m. attrs . list ( "doc" ) ) {
439437 for attr in attrs {
440438 match * attr {
441439 clean:: NameValue ( ref x, ref s)
442440 if "html_favicon_url" == * x => {
443- cx . layout . favicon = s. to_string ( ) ;
441+ scx . layout . favicon = s. to_string ( ) ;
444442 }
445443 clean:: NameValue ( ref x, ref s)
446444 if "html_logo_url" == * x => {
447- cx . layout . logo = s. to_string ( ) ;
445+ scx . layout . logo = s. to_string ( ) ;
448446 }
449447 clean:: NameValue ( ref x, ref s)
450448 if "html_playground_url" == * x => {
451- cx . layout . playground_url = s. to_string ( ) ;
449+ scx . layout . playground_url = s. to_string ( ) ;
452450 markdown:: PLAYGROUND_KRATE . with ( |slot| {
453451 if slot. borrow ( ) . is_none ( ) {
454452 let name = krate. name . clone ( ) ;
@@ -458,16 +456,25 @@ pub fn run(mut krate: clean::Crate,
458456 }
459457 clean:: NameValue ( ref x, ref s)
460458 if "issue_tracker_base_url" == * x => {
461- cx . issue_tracker_base_url = Some ( s. to_string ( ) ) ;
459+ scx . issue_tracker_base_url = Some ( s. to_string ( ) ) ;
462460 }
463461 clean:: Word ( ref x)
464462 if "html_no_source" == * x => {
465- cx . include_sources = false ;
463+ scx . include_sources = false ;
466464 }
467465 _ => { }
468466 }
469467 }
470468 }
469+ try_err ! ( mkdir( & dst) , & dst) ;
470+ krate = render_sources ( & dst, & mut scx, krate) ?;
471+ let cx = Context {
472+ current : Vec :: new ( ) ,
473+ root_path : String :: new ( ) ,
474+ dst : dst,
475+ render_redirect_pages : false ,
476+ shared : Arc :: new ( scx) ,
477+ } ;
471478
472479 // Crawl the crate to build various caches used for the output
473480 let analysis = :: ANALYSISKEY . with ( |a| a. clone ( ) ) ;
@@ -538,7 +545,6 @@ pub fn run(mut krate: clean::Crate,
538545 CURRENT_LOCATION_KEY . with ( |s| s. borrow_mut ( ) . clear ( ) ) ;
539546
540547 write_shared ( & cx, & krate, & * cache, index) ?;
541- let krate = render_sources ( & mut cx, krate) ?;
542548
543549 // And finally render the whole crate's documentation
544550 cx. krate ( krate)
@@ -760,16 +766,16 @@ fn write_shared(cx: &Context,
760766 Ok ( ( ) )
761767}
762768
763- fn render_sources ( cx : & mut Context ,
769+ fn render_sources ( dst : & Path , scx : & mut SharedContext ,
764770 krate : clean:: Crate ) -> Result < clean:: Crate , Error > {
765771 info ! ( "emitting source files" ) ;
766- let dst = cx . dst . join ( "src" ) ;
772+ let dst = dst. join ( "src" ) ;
767773 try_err ! ( mkdir( & dst) , & dst) ;
768774 let dst = dst. join ( & krate. name ) ;
769775 try_err ! ( mkdir( & dst) , & dst) ;
770776 let mut folder = SourceCollector {
771777 dst : dst,
772- cx : cx ,
778+ scx : scx ,
773779 } ;
774780 Ok ( folder. fold_crate ( krate) )
775781}
@@ -847,7 +853,7 @@ impl<'a> DocFolder for SourceCollector<'a> {
847853 fn fold_item ( & mut self , item : clean:: Item ) -> Option < clean:: Item > {
848854 // If we're including source files, and we haven't seen this file yet,
849855 // then we need to render it out to the filesystem
850- if self . cx . include_sources
856+ if self . scx . include_sources
851857 // skip all invalid spans
852858 && item. source . filename != ""
853859 // macros from other libraries get special filenames which we can
@@ -860,7 +866,7 @@ impl<'a> DocFolder for SourceCollector<'a> {
860866 // something like that), so just don't include sources for the
861867 // entire crate. The other option is maintaining this mapping on a
862868 // per-file basis, but that's probably not worth it...
863- self . cx
869+ self . scx
864870 . include_sources = match self . emit_source ( & item. source . filename ) {
865871 Ok ( ( ) ) => true ,
866872 Err ( e) => {
@@ -880,7 +886,7 @@ impl<'a> SourceCollector<'a> {
880886 /// Renders the given filename into its corresponding HTML source file.
881887 fn emit_source ( & mut self , filename : & str ) -> io:: Result < ( ) > {
882888 let p = PathBuf :: from ( filename) ;
883- if self . cx . local_sources . contains_key ( & p) {
889+ if self . scx . local_sources . contains_key ( & p) {
884890 // We've already emitted this source
885891 return Ok ( ( ) ) ;
886892 }
@@ -901,7 +907,7 @@ impl<'a> SourceCollector<'a> {
901907 let mut cur = self . dst . clone ( ) ;
902908 let mut root_path = String :: from ( "../../" ) ;
903909 let mut href = String :: new ( ) ;
904- clean_srcpath ( & self . cx . src_root , & p, false , |component| {
910+ clean_srcpath ( & self . scx . src_root , & p, false , |component| {
905911 cur. push ( component) ;
906912 mkdir ( & cur) . unwrap ( ) ;
907913 root_path. push_str ( "../" ) ;
@@ -925,10 +931,10 @@ impl<'a> SourceCollector<'a> {
925931 description : & desc,
926932 keywords : BASIC_KEYWORDS ,
927933 } ;
928- layout:: render ( & mut w, & self . cx . layout ,
934+ layout:: render ( & mut w, & self . scx . layout ,
929935 & page, & ( "" ) , & Source ( contents) ) ?;
930936 w. flush ( ) ?;
931- self . cx . local_sources . insert ( p, href) ;
937+ self . scx . local_sources . insert ( p, href) ;
932938 Ok ( ( ) )
933939 }
934940}
@@ -1265,10 +1271,10 @@ impl Context {
12651271 let tyname = shortty ( it) . to_static_str ( ) ;
12661272 let desc = if it. is_crate ( ) {
12671273 format ! ( "API documentation for the Rust `{}` crate." ,
1268- cx. layout. krate)
1274+ cx. shared . layout. krate)
12691275 } else {
12701276 format ! ( "API documentation for the Rust `{}` {} in crate `{}`." ,
1271- it. name. as_ref( ) . unwrap( ) , tyname, cx. layout. krate)
1277+ it. name. as_ref( ) . unwrap( ) , tyname, cx. shared . layout. krate)
12721278 } ;
12731279 let keywords = make_item_keywords ( it) ;
12741280 let page = layout:: Page {
@@ -1286,7 +1292,7 @@ impl Context {
12861292 // write syscall all the time.
12871293 let mut writer = BufWriter :: new ( w) ;
12881294 if !cx. render_redirect_pages {
1289- layout:: render ( & mut writer, & cx. layout , & page,
1295+ layout:: render ( & mut writer, & cx. shared . layout , & page,
12901296 & Sidebar { cx : cx, item : it } ,
12911297 & Item { cx : cx, item : it } ) ?;
12921298
@@ -1434,10 +1440,11 @@ impl<'a> Item<'a> {
14341440 // know the span, so we plow forward and generate a proper url. The url
14351441 // has anchors for the line numbers that we're linking to.
14361442 } else if self . item . def_id . is_local ( ) {
1437- self . cx . local_sources . get ( & PathBuf :: from ( & self . item . source . filename ) ) . map ( |path| {
1443+ let path = PathBuf :: from ( & self . item . source . filename ) ;
1444+ self . cx . shared . local_sources . get ( & path) . map ( |path| {
14381445 format ! ( "{root}src/{krate}/{path}#{href}" ,
14391446 root = self . cx. root_path,
1440- krate = self . cx. layout. krate,
1447+ krate = self . cx. shared . layout. krate,
14411448 path = path,
14421449 href = href)
14431450 } )
@@ -1520,7 +1527,7 @@ impl<'a> fmt::Display for Item<'a> {
15201527 // [src] link in the downstream documentation will actually come back to
15211528 // this page, and this link will be auto-clicked. The `id` attribute is
15221529 // used to find the link to auto-click.
1523- if self . cx . include_sources && !is_primitive {
1530+ if self . cx . shared . include_sources && !is_primitive {
15241531 if let Some ( l) = self . href ( ) {
15251532 write ! ( fmt, "<a id='src-{}' class='srclink' \
15261533 href='{}' title='{}'>[src]</a>",
@@ -1752,7 +1759,7 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Optio
17521759 format ! ( "Deprecated{}{}" , since, Markdown ( & reason) )
17531760 } else if stab. level == stability:: Unstable {
17541761 let unstable_extra = if show_reason {
1755- match ( !stab. feature . is_empty ( ) , & cx. issue_tracker_base_url , stab. issue ) {
1762+ match ( !stab. feature . is_empty ( ) , & cx. shared . issue_tracker_base_url , stab. issue ) {
17561763 ( true , & Some ( ref tracker_url) , Some ( issue_no) ) if issue_no > 0 =>
17571764 format ! ( " (<code>{}</code> <a href=\" {}{}\" >#{}</a>)" ,
17581765 Escape ( & stab. feature) , tracker_url, issue_no, issue_no) ,
0 commit comments