@@ -25,6 +25,7 @@ use std::ffi::OsString;
25
25
use std:: collections:: hash_map:: Entry ;
26
26
use std:: iter:: once;
27
27
use std:: str:: FromStr ;
28
+ use std:: any:: Any ;
28
29
29
30
use indexmap:: IndexMap ;
30
31
use itertools:: Itertools ;
@@ -42,7 +43,7 @@ use super::{collect_paths_for_type, ensure_trailing_slash, Context, RenderMode};
42
43
use crate :: html:: render:: search_index:: build_index;
43
44
use crate :: html:: render:: sorted_json:: SortedJson ;
44
45
use crate :: html:: render:: offset_template:: { self , OffsetTemplate } ;
45
- use crate :: clean:: { Crate , Item , ItemId , ItemKind , types :: ExternalCrate } ;
46
+ use crate :: clean:: { Crate , Item , ItemId , ItemKind } ;
46
47
use crate :: config:: { EmitType , RenderOptions , PathToParts } ;
47
48
use crate :: docfs:: PathError ;
48
49
use crate :: error:: Error ;
@@ -63,6 +64,40 @@ use crate::{try_err, try_none};
63
64
// string faster loading tetchnique
64
65
// run rest of the tests and fix things up
65
66
67
+ #[ derive( Serialize , Deserialize , Clone , Debug ) ]
68
+ struct CrateInfo {
69
+ src_files_js : PartsAndLocations < SourcesPart > ,
70
+ search_index_js : PartsAndLocations < SearchIndexPart > ,
71
+ all_crates : PartsAndLocations < AllCratesPart > ,
72
+ crates_index : PartsAndLocations < CratesIndexPart > ,
73
+ trait_impl : PartsAndLocations < TraitAliasPart > ,
74
+ type_impl : PartsAndLocations < TypeAliasPart > ,
75
+ }
76
+
77
+ impl CrateInfo {
78
+ fn get < T : ' static > ( & self ) -> Option < & PartsAndLocations < T > > {
79
+ ( & self . src_files_js as & dyn Any ) . downcast_ref ( )
80
+ . or_else ( || ( & self . search_index_js as & dyn Any ) . downcast_ref ( ) )
81
+ . or_else ( || ( & self . all_crates as & dyn Any ) . downcast_ref ( ) )
82
+ . or_else ( || ( & self . crates_index as & dyn Any ) . downcast_ref ( ) )
83
+ . or_else ( || ( & self . trait_impl as & dyn Any ) . downcast_ref ( ) )
84
+ . or_else ( || ( & self . type_impl as & dyn Any ) . downcast_ref ( ) )
85
+ }
86
+
87
+ fn read ( parts_paths : & FxHashMap < String , PathToParts > ) -> Result < Vec < Self > , Error > {
88
+ parts_paths. iter ( )
89
+ . map ( |( crate_name, parts_path) | {
90
+ let path = parts_path. crate_info_path ( crate_name) ;
91
+ let parts = try_err ! ( fs:: read( & path) , & path) ;
92
+ let parts: CrateInfo = try_err ! ( serde_json:: from_slice( & parts) , & path) ;
93
+ Ok :: < _ , Error > ( parts)
94
+ } )
95
+ . collect :: < Result < Vec < CrateInfo > , Error > > ( )
96
+ }
97
+
98
+ }
99
+
100
+
66
101
pub ( crate ) fn write_shared (
67
102
cx : & mut Context < ' _ > ,
68
103
krate : & Crate ,
@@ -78,37 +113,37 @@ pub(crate) fn write_shared(
78
113
let crate_name = krate. name ( cx. tcx ( ) ) ;
79
114
let crate_name = crate_name. as_str ( ) ; // rand
80
115
let crate_name_json = SortedJson :: serialize ( crate_name) ; // "rand"
81
-
82
- let sources = PartsAndLocations :: < SourcesPart > :: get ( cx, & crate_name_json) ?;
83
116
let SerializedSearchIndex { index, desc } = build_index ( & krate, & mut Rc :: get_mut ( & mut cx. shared ) . unwrap ( ) . cache , tcx) ;
84
- let search_index = PartsAndLocations :: < SearchIndexPart > :: get ( cx, index) ?;
85
- let all_crates = PartsAndLocations :: < AllCratesPart > :: get ( crate_name_json. clone ( ) ) ?;
86
117
let external_crates = hack_get_external_crate_names ( cx) ?;
87
- let crates_index = PartsAndLocations :: < CratesIndexPart > :: get ( & crate_name, & external_crates) ?;
88
- let trait_aliases = PartsAndLocations :: < TraitAliasPart > :: get ( cx, & crate_name_json) ?;
89
- let type_aliases = PartsAndLocations :: < TypeAliasPart > :: get ( cx, krate, & crate_name_json) ?;
118
+ let info = CrateInfo {
119
+ src_files_js : PartsAndLocations :: < SourcesPart > :: get ( cx, & crate_name_json) ?,
120
+ search_index_js : PartsAndLocations :: < SearchIndexPart > :: get ( cx, index) ?,
121
+ all_crates : PartsAndLocations :: < AllCratesPart > :: get ( crate_name_json. clone ( ) ) ?,
122
+ crates_index : PartsAndLocations :: < CratesIndexPart > :: get ( & crate_name, & external_crates) ?,
123
+ trait_impl : PartsAndLocations :: < TraitAliasPart > :: get ( cx, & crate_name_json) ?,
124
+ type_impl : PartsAndLocations :: < TypeAliasPart > :: get ( cx, krate, & crate_name_json) ?,
125
+ } ;
90
126
91
127
if let Some ( parts_out_dir) = & opt. parts_out_dir {
92
- sources. write ( cx, parts_out_dir) ?;
93
- search_index. write ( cx, parts_out_dir) ?;
94
- all_crates. write ( cx, parts_out_dir) ?;
95
- crates_index. write ( cx, parts_out_dir) ?;
96
- trait_aliases. write ( cx, parts_out_dir) ?;
97
- type_aliases. write ( cx, parts_out_dir) ?;
128
+ let path = parts_out_dir. crate_info_path ( & crate_name) ;
129
+ write_create_parents ( cx, path, serde_json:: to_string ( & info) . unwrap ( ) ) ?;
98
130
}
99
131
132
+ let mut crates_info = CrateInfo :: read ( & opt. parts_paths ) ?;
133
+ crates_info. push ( info) ;
134
+
100
135
if opt. write_rendered_cci {
101
136
write_static_files ( cx, & opt) ?;
102
137
write_search_desc ( cx, & krate, & desc) ?;
103
138
if opt. emit . is_empty ( ) || opt. emit . contains ( & EmitType :: InvocationSpecific ) {
104
139
if cx. include_sources {
105
- write_rendered_cci ( cx, opt. read_rendered_cci , & opt . parts_paths , & sources ) ?;
140
+ write_rendered_cci :: < SourcesPart > ( cx, opt. read_rendered_cci , & crates_info ) ?;
106
141
}
107
- write_rendered_cci ( cx, opt. read_rendered_cci , & opt . parts_paths , & search_index ) ?;
108
- write_rendered_cci ( cx, opt. read_rendered_cci , & opt . parts_paths , & all_crates ) ?;
142
+ write_rendered_cci :: < SearchIndexPart > ( cx, opt. read_rendered_cci , & crates_info ) ?;
143
+ write_rendered_cci :: < AllCratesPart > ( cx, opt. read_rendered_cci , & crates_info ) ?;
109
144
}
110
- write_rendered_cci ( cx, opt. read_rendered_cci , & opt . parts_paths , & trait_aliases ) ?;
111
- write_rendered_cci ( cx, opt. read_rendered_cci , & opt . parts_paths , & type_aliases ) ?;
145
+ write_rendered_cci :: < TraitAliasPart > ( cx, opt. read_rendered_cci , & crates_info ) ?;
146
+ write_rendered_cci :: < TypeAliasPart > ( cx, opt. read_rendered_cci , & crates_info ) ?;
112
147
match & opt. index_page {
113
148
Some ( index_page) if opt. enable_index_page => {
114
149
let mut md_opts = opt. clone ( ) ;
@@ -117,7 +152,7 @@ pub(crate) fn write_shared(
117
152
try_err ! ( crate :: markdown:: render( & index_page, md_opts, cx. shared. edition( ) ) , & index_page) ;
118
153
}
119
154
None if opt. enable_index_page => {
120
- write_rendered_cci ( cx, opt. read_rendered_cci , & opt . parts_paths , & crates_index ) ?;
155
+ write_rendered_cci :: < CratesIndexPart > ( cx, opt. read_rendered_cci , & crates_info ) ?;
121
156
}
122
157
_ => { } , // they don't want an index page
123
158
}
@@ -206,6 +241,7 @@ struct Part<T, U> {
206
241
}
207
242
208
243
impl < T , U : fmt:: Display > fmt:: Display for Part < T , U > {
244
+ /// Writes serialized JSON
209
245
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
210
246
write ! ( f, "{}" , self . item)
211
247
}
@@ -215,12 +251,11 @@ pub(crate) trait NamedPart: Sized {
215
251
/// Identifies the kind of cross crate information.
216
252
///
217
253
/// The cci type name in `doc.parts/<cci type>`
218
- const NAME : & ' static str ;
219
254
type FileFormat : offset_template:: FileFormat ;
220
255
fn blank_template ( cx : & Context < ' _ > ) -> OffsetTemplate < Self :: FileFormat > ;
221
256
}
222
257
223
- /// Paths (relative to ` doc/` ) and their pre-merge contents
258
+ /// Paths (relative to the doc root ) and their pre-merge contents
224
259
#[ derive( Serialize , Deserialize , Debug , Clone ) ]
225
260
#[ serde( transparent) ]
226
261
struct PartsAndLocations < P > {
@@ -245,22 +280,10 @@ impl<T, U> PartsAndLocations<Part<T, U>> {
245
280
}
246
281
}
247
282
248
- impl < T , U : Serialize > PartsAndLocations < Part < T , U > >
249
- where Part < T , U > : NamedPart ,
250
- {
251
- fn write ( & self , cx : & mut Context < ' _ > , parts_path : & PathToParts ) -> Result < ( ) , Error > {
252
- let name = ExternalCrate :: LOCAL . name ( cx. tcx ( ) ) ;
253
- let path = parts_path. cci_path :: < Part < T , U > > ( name. as_str ( ) ) ;
254
- write_create_parents ( cx, path, serde_json:: to_string ( self ) . unwrap ( ) ) ?;
255
- Ok ( ( ) )
256
- }
257
- }
258
-
259
283
#[ derive( Serialize , Deserialize , Clone , Default , Debug ) ]
260
284
struct SearchIndex ;
261
285
type SearchIndexPart = Part < SearchIndex , SortedJson > ;
262
286
impl NamedPart for SearchIndexPart {
263
- const NAME : & ' static str = "search-index-js" ;
264
287
type FileFormat = offset_template:: Js ;
265
288
fn blank_template ( _cx : & Context < ' _ > ) -> OffsetTemplate < Self :: FileFormat > {
266
289
OffsetTemplate :: before_after ( r"var searchIndex = new Map([" , r"]);
@@ -279,7 +302,6 @@ impl PartsAndLocations<SearchIndexPart> {
279
302
struct AllCrates ;
280
303
type AllCratesPart = Part < AllCrates , SortedJson > ;
281
304
impl NamedPart for AllCratesPart {
282
- const NAME : & ' static str = "crates-js" ;
283
305
type FileFormat = offset_template:: Js ;
284
306
fn blank_template ( _cx : & Context < ' _ > ) -> OffsetTemplate < Self :: FileFormat > {
285
307
OffsetTemplate :: before_after ( "window.ALL_CRATES = [" , "];" )
@@ -314,7 +336,6 @@ fn hack_get_external_crate_names(cx: &Context<'_>) -> Result<Vec<String>, Error>
314
336
struct CratesIndex ;
315
337
type CratesIndexPart = Part < CratesIndex , String > ;
316
338
impl NamedPart for CratesIndexPart {
317
- const NAME : & ' static str = "index-html" ;
318
339
type FileFormat = offset_template:: Html ;
319
340
fn blank_template ( cx : & Context < ' _ > ) -> OffsetTemplate < Self :: FileFormat > {
320
341
let mut magic = String :: from ( "\u{FFFC} " ) ;
@@ -360,7 +381,6 @@ impl PartsAndLocations<CratesIndexPart> {
360
381
struct Sources ;
361
382
type SourcesPart = Part < Sources , SortedJson > ;
362
383
impl NamedPart for SourcesPart {
363
- const NAME : & ' static str = "src-files-js" ;
364
384
type FileFormat = offset_template:: Js ;
365
385
fn blank_template ( _cx : & Context < ' _ > ) -> OffsetTemplate < Self :: FileFormat > {
366
386
// This needs to be `var`, not `const`.
@@ -454,7 +474,6 @@ impl Hierarchy {
454
474
struct TypeAlias ;
455
475
type TypeAliasPart = Part < TypeAlias , SortedJson > ;
456
476
impl NamedPart for TypeAliasPart {
457
- const NAME : & ' static str = "type-impl" ;
458
477
type FileFormat = offset_template:: Js ;
459
478
fn blank_template ( _cx : & Context < ' _ > ) -> OffsetTemplate < Self :: FileFormat > {
460
479
OffsetTemplate :: before_after ( r"(function() {
@@ -570,7 +589,6 @@ impl PartsAndLocations<TypeAliasPart> {
570
589
struct TraitAlias ;
571
590
type TraitAliasPart = Part < TraitAlias , SortedJson > ;
572
591
impl NamedPart for TraitAliasPart {
573
- const NAME : & ' static str = "trait-impl" ;
574
592
type FileFormat = offset_template:: Js ;
575
593
fn blank_template ( _cx : & Context < ' _ > ) -> OffsetTemplate < Self :: FileFormat > {
576
594
OffsetTemplate :: before_after ( r"(function() {
@@ -830,25 +848,16 @@ fn write_create_parents(cx: &mut Context<'_>, path: PathBuf, content: String) ->
830
848
Ok ( ( ) )
831
849
}
832
850
833
- fn write_rendered_cci < T : NamedPart + DeserializeOwned + fmt:: Display + fmt:: Debug > (
851
+ /// info from this crate and the --include-info-json'd crates
852
+ fn write_rendered_cci < T : NamedPart + DeserializeOwned + fmt:: Display + fmt:: Debug + Any > (
834
853
cx : & mut Context < ' _ > ,
835
854
read_rendered_cci : bool ,
836
- parts_paths : & FxHashMap < String , PathToParts > ,
837
- our_parts_and_locations : & PartsAndLocations < T > ,
855
+ crates_info : & [ CrateInfo ] ,
838
856
) -> Result < ( ) , Error > where <T as NamedPart >:: FileFormat : std:: fmt:: Debug {
839
857
// read parts from disk
840
- let path_parts = parts_paths. iter ( )
841
- . map ( |( crate_name, parts_path) | {
842
- let path = parts_path. cci_path :: < T > ( crate_name) ;
843
- let parts = try_err ! ( fs:: read( & path) , & path) ;
844
- let parts: PartsAndLocations :: < T > = try_err ! ( serde_json:: from_slice( & parts) , & path) ;
845
- Ok :: < _ , Error > ( parts)
846
- } )
847
- . collect :: < Result < Vec < PartsAndLocations < T > > , Error > > ( ) ?;
848
- let path_parts = path_parts. iter ( )
849
- . map ( |parts_and_locations| parts_and_locations. parts . iter ( ) )
850
- . flatten ( )
851
- . chain ( our_parts_and_locations. parts . iter ( ) ) ;
858
+ let path_parts = crates_info. iter ( )
859
+ . map ( |crate_info| crate_info. get :: < T > ( ) . unwrap ( ) . parts . iter ( ) )
860
+ . flatten ( ) ;
852
861
// read previous rendered cci from storage, append to them
853
862
let mut templates: FxHashMap < PathBuf , OffsetTemplate < T :: FileFormat > > = Default :: default ( ) ;
854
863
for ( path, part) in path_parts {
0 commit comments