@@ -52,7 +52,7 @@ use std::sync::Arc;
52
52
53
53
use externalfiles:: ExternalHtml ;
54
54
55
- use serialize:: json:: { self , ToJson } ;
55
+ use serialize:: json:: { ToJson , Json , as_json } ;
56
56
use syntax:: { abi, ast} ;
57
57
use syntax:: feature_gate:: UnstableFeatures ;
58
58
use rustc:: middle:: cstore:: LOCAL_CRATE ;
@@ -290,22 +290,40 @@ struct IndexItem {
290
290
path : String ,
291
291
desc : String ,
292
292
parent : Option < DefId > ,
293
+ parent_idx : Option < usize > ,
293
294
search_type : Option < IndexItemFunctionType > ,
294
295
}
295
296
297
+ impl ToJson for IndexItem {
298
+ fn to_json ( & self ) -> Json {
299
+ assert_eq ! ( self . parent. is_some( ) , self . parent_idx. is_some( ) ) ;
300
+
301
+ let mut data = Vec :: with_capacity ( 6 ) ;
302
+ data. push ( ( self . ty as usize ) . to_json ( ) ) ;
303
+ data. push ( self . name . to_json ( ) ) ;
304
+ data. push ( self . path . to_json ( ) ) ;
305
+ data. push ( self . desc . to_json ( ) ) ;
306
+ data. push ( self . parent_idx . to_json ( ) ) ;
307
+ data. push ( self . search_type . to_json ( ) ) ;
308
+
309
+ Json :: Array ( data)
310
+ }
311
+ }
312
+
296
313
/// A type used for the search index.
297
314
struct Type {
298
315
name : Option < String > ,
299
316
}
300
317
301
- impl fmt:: Display for Type {
302
- /// Formats type as {name: $name}.
303
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
304
- // Wrapping struct fmt should never call us when self.name is None,
305
- // but just to be safe we write `null` in that case.
318
+ impl ToJson for Type {
319
+ fn to_json ( & self ) -> Json {
306
320
match self . name {
307
- Some ( ref n) => write ! ( f, "{{\" name\" :\" {}\" }}" , n) ,
308
- None => write ! ( f, "null" )
321
+ Some ( ref name) => {
322
+ let mut data = BTreeMap :: new ( ) ;
323
+ data. insert ( "name" . to_owned ( ) , name. to_json ( ) ) ;
324
+ Json :: Object ( data)
325
+ } ,
326
+ None => Json :: Null
309
327
}
310
328
}
311
329
}
@@ -316,26 +334,17 @@ struct IndexItemFunctionType {
316
334
output : Option < Type >
317
335
}
318
336
319
- impl fmt:: Display for IndexItemFunctionType {
320
- /// Formats a full fn type as a JSON {inputs: [Type], outputs: Type/null}.
321
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
337
+ impl ToJson for IndexItemFunctionType {
338
+ fn to_json ( & self ) -> Json {
322
339
// If we couldn't figure out a type, just write `null`.
323
- if self . inputs . iter ( ) . any ( |ref i| i. name . is_none ( ) ) ||
324
- ( self . output . is_some ( ) && self . output . as_ref ( ) . unwrap ( ) . name . is_none ( ) ) {
325
- return write ! ( f, "null" )
340
+ if self . inputs . iter ( ) . chain ( self . output . iter ( ) ) . any ( |ref i| i. name . is_none ( ) ) {
341
+ Json :: Null
342
+ } else {
343
+ let mut data = BTreeMap :: new ( ) ;
344
+ data. insert ( "inputs" . to_owned ( ) , self . inputs . to_json ( ) ) ;
345
+ data. insert ( "output" . to_owned ( ) , self . output . to_json ( ) ) ;
346
+ Json :: Object ( data)
326
347
}
327
-
328
- let inputs: Vec < String > = self . inputs . iter ( ) . map ( |ref t| {
329
- format ! ( "{}" , t)
330
- } ) . collect ( ) ;
331
- try!( write ! ( f, "{{\" inputs\" :[{}],\" output\" :" , inputs. join( "," ) ) ) ;
332
-
333
- match self . output {
334
- Some ( ref t) => try!( write ! ( f, "{}" , t) ) ,
335
- None => try!( write ! ( f, "null" ) )
336
- } ;
337
-
338
- Ok ( try!( write ! ( f, "}}" ) ) )
339
348
}
340
349
}
341
350
@@ -534,101 +543,79 @@ pub fn run(mut krate: clean::Crate,
534
543
cx. krate ( krate)
535
544
}
536
545
546
+ /// Build the search index from the collected metadata
537
547
fn build_index ( krate : & clean:: Crate , cache : & mut Cache ) -> String {
538
- // Build the search index from the collected metadata
539
548
let mut nodeid_to_pathid = HashMap :: new ( ) ;
540
- let mut pathid_to_nodeid = Vec :: new ( ) ;
541
- {
542
- let Cache { ref mut search_index,
543
- ref orphan_methods,
544
- ref mut paths, .. } = * cache;
545
-
546
- // Attach all orphan methods to the type's definition if the type
547
- // has since been learned.
548
- for & ( did, ref item) in orphan_methods {
549
- match paths. get ( & did) {
550
- Some ( & ( ref fqp, _) ) => {
551
- // Needed to determine `self` type.
552
- let parent_basename = Some ( fqp[ fqp. len ( ) - 1 ] . clone ( ) ) ;
553
- search_index. push ( IndexItem {
554
- ty : shortty ( item) ,
555
- name : item. name . clone ( ) . unwrap ( ) ,
556
- path : fqp[ ..fqp. len ( ) - 1 ] . join ( "::" ) ,
557
- desc : Escape ( & shorter ( item. doc_value ( ) ) ) . to_string ( ) ,
558
- parent : Some ( did) ,
559
- search_type : get_index_search_type ( & item, parent_basename) ,
560
- } ) ;
561
- } ,
562
- None => { }
563
- }
564
- }
565
-
566
- // Reduce `NodeId` in paths into smaller sequential numbers,
567
- // and prune the paths that do not appear in the index.
568
- for item in search_index. iter ( ) {
569
- match item. parent {
570
- Some ( nodeid) => {
571
- if !nodeid_to_pathid. contains_key ( & nodeid) {
572
- let pathid = pathid_to_nodeid. len ( ) ;
573
- nodeid_to_pathid. insert ( nodeid, pathid) ;
574
- pathid_to_nodeid. push ( nodeid) ;
575
- }
576
- }
577
- None => { }
578
- }
549
+ let mut crate_items = Vec :: with_capacity ( cache. search_index . len ( ) ) ;
550
+ let mut crate_paths = Vec :: < Json > :: new ( ) ;
551
+
552
+ let Cache { ref mut search_index,
553
+ ref orphan_methods,
554
+ ref mut paths, .. } = * cache;
555
+
556
+ // Attach all orphan methods to the type's definition if the type
557
+ // has since been learned.
558
+ for & ( did, ref item) in orphan_methods {
559
+ match paths. get ( & did) {
560
+ Some ( & ( ref fqp, _) ) => {
561
+ // Needed to determine `self` type.
562
+ let parent_basename = Some ( fqp[ fqp. len ( ) - 1 ] . clone ( ) ) ;
563
+ search_index. push ( IndexItem {
564
+ ty : shortty ( item) ,
565
+ name : item. name . clone ( ) . unwrap ( ) ,
566
+ path : fqp[ ..fqp. len ( ) - 1 ] . join ( "::" ) ,
567
+ desc : Escape ( & shorter ( item. doc_value ( ) ) ) . to_string ( ) ,
568
+ parent : Some ( did) ,
569
+ parent_idx : None ,
570
+ search_type : get_index_search_type ( & item, parent_basename) ,
571
+ } ) ;
572
+ } ,
573
+ None => { }
579
574
}
580
- assert_eq ! ( nodeid_to_pathid. len( ) , pathid_to_nodeid. len( ) ) ;
581
575
}
582
576
583
- // Collect the index into a string
584
- let mut w = io:: Cursor :: new ( Vec :: new ( ) ) ;
585
- write ! ( & mut w, r#"searchIndex['{}'] = {{"items":["# , krate. name) . unwrap ( ) ;
577
+ // Reduce `NodeId` in paths into smaller sequential numbers,
578
+ // and prune the paths that do not appear in the index.
579
+ let mut lastpath = String :: new ( ) ;
580
+ let mut lastpathid = 0usize ;
586
581
587
- let mut lastpath = "" . to_string ( ) ;
588
- for ( i, item) in cache. search_index . iter ( ) . enumerate ( ) {
589
- // Omit the path if it is same to that of the prior item.
590
- let path;
591
- if lastpath == item. path {
592
- path = "" ;
593
- } else {
594
- lastpath = item. path . to_string ( ) ;
595
- path = & item. path ;
596
- } ;
582
+ for item in search_index {
583
+ item. parent_idx = item. parent . map ( |nodeid| {
584
+ if nodeid_to_pathid. contains_key ( & nodeid) {
585
+ * nodeid_to_pathid. get ( & nodeid) . unwrap ( )
586
+ } else {
587
+ let pathid = lastpathid;
588
+ nodeid_to_pathid. insert ( nodeid, pathid) ;
589
+ lastpathid += 1 ;
597
590
598
- if i > 0 {
599
- write ! ( & mut w, "," ) . unwrap ( ) ;
600
- }
601
- write ! ( & mut w, r#"[{},"{}","{}",{}"# ,
602
- item. ty as usize , item. name, path,
603
- item. desc. to_json( ) . to_string( ) ) . unwrap ( ) ;
604
- match item. parent {
605
- Some ( nodeid) => {
606
- let pathid = * nodeid_to_pathid. get ( & nodeid) . unwrap ( ) ;
607
- write ! ( & mut w, ",{}" , pathid) . unwrap ( ) ;
591
+ let & ( ref fqp, short) = paths. get ( & nodeid) . unwrap ( ) ;
592
+ crate_paths. push ( ( ( short as usize ) , fqp. last ( ) . unwrap ( ) . clone ( ) ) . to_json ( ) ) ;
593
+ pathid
608
594
}
609
- None => write ! ( & mut w, ",null" ) . unwrap ( )
610
- }
611
- match item. search_type {
612
- Some ( ref t) => write ! ( & mut w, ",{}" , t) . unwrap ( ) ,
613
- None => write ! ( & mut w, ",null" ) . unwrap ( )
614
- }
615
- write ! ( & mut w, "]" ) . unwrap ( ) ;
616
- }
617
-
618
- write ! ( & mut w, r#"],"paths":["# ) . unwrap ( ) ;
595
+ } ) ;
619
596
620
- for ( i, & did) in pathid_to_nodeid. iter ( ) . enumerate ( ) {
621
- let & ( ref fqp, short) = cache. paths . get ( & did) . unwrap ( ) ;
622
- if i > 0 {
623
- write ! ( & mut w, "," ) . unwrap ( ) ;
597
+ // Omit the parent path if it is same to that of the prior item.
598
+ if lastpath == item. path {
599
+ item. path . clear ( ) ;
600
+ } else {
601
+ lastpath = item. path . clone ( ) ;
624
602
}
625
- write ! ( & mut w, r#"[{},"{}"]"# ,
626
- short as usize , * fqp. last( ) . unwrap( ) ) . unwrap ( ) ;
603
+ crate_items. push ( item. to_json ( ) ) ;
627
604
}
628
605
629
- write ! ( & mut w, "]}};" ) . unwrap ( ) ;
606
+ let crate_doc = krate. module . as_ref ( ) . map ( |module| {
607
+ Escape ( & shorter ( module. doc_value ( ) ) ) . to_string ( )
608
+ } ) . unwrap_or ( String :: new ( ) ) ;
630
609
631
- String :: from_utf8 ( w. into_inner ( ) ) . unwrap ( )
610
+ let mut crate_data = BTreeMap :: new ( ) ;
611
+ crate_data. insert ( "doc" . to_owned ( ) , Json :: String ( crate_doc) ) ;
612
+ crate_data. insert ( "items" . to_owned ( ) , Json :: Array ( crate_items) ) ;
613
+ crate_data. insert ( "paths" . to_owned ( ) , Json :: Array ( crate_paths) ) ;
614
+
615
+ // Collect the index into a string
616
+ format ! ( "searchIndex[{}] = {};" ,
617
+ as_json( & krate. name) ,
618
+ Json :: Object ( crate_data) )
632
619
}
633
620
634
621
fn write_shared ( cx : & Context ,
@@ -693,7 +680,7 @@ fn write_shared(cx: &Context,
693
680
if !line. starts_with ( key) {
694
681
continue
695
682
}
696
- if line. starts_with ( & format ! ( "{}['{}']" , key, krate) ) {
683
+ if line. starts_with ( & format ! ( r# "{}["{}"]"# , key, krate) ) {
697
684
continue
698
685
}
699
686
ret. push ( line. to_string ( ) ) ;
@@ -1067,6 +1054,7 @@ impl DocFolder for Cache {
1067
1054
path : path. join ( "::" ) . to_string ( ) ,
1068
1055
desc : Escape ( & shorter ( item. doc_value ( ) ) ) . to_string ( ) ,
1069
1056
parent : parent,
1057
+ parent_idx : None ,
1070
1058
search_type : get_index_search_type ( & item, parent_basename) ,
1071
1059
} ) ;
1072
1060
}
@@ -1387,7 +1375,7 @@ impl Context {
1387
1375
let js_dst = this. dst . join ( "sidebar-items.js" ) ;
1388
1376
let mut js_out = BufWriter :: new ( try_err ! ( File :: create( & js_dst) , & js_dst) ) ;
1389
1377
try_err ! ( write!( & mut js_out, "initSidebarItems({});" ,
1390
- json :: as_json( & items) ) , & js_dst) ;
1378
+ as_json( & items) ) , & js_dst) ;
1391
1379
}
1392
1380
1393
1381
for item in m. items {
0 commit comments