@@ -1087,7 +1087,8 @@ impl<'a> SourceCollector<'a> {
1087
1087
href. push_str ( component) ;
1088
1088
href. push ( '/' ) ;
1089
1089
} ) ;
1090
- let mut fname = p. file_name ( ) . expect ( "source has no filename" )
1090
+ let mut fname = p. file_name ( )
1091
+ . expect ( "source has no filename" )
1091
1092
. to_os_string ( ) ;
1092
1093
fname. push ( ".html" ) ;
1093
1094
cur. push ( & fname) ;
@@ -1373,6 +1374,135 @@ impl<'a> Cache {
1373
1374
}
1374
1375
}
1375
1376
1377
+ #[ derive( Debug , Eq , PartialEq , Hash ) ]
1378
+ struct ItemEntry {
1379
+ url : String ,
1380
+ name : String ,
1381
+ }
1382
+
1383
+ impl ItemEntry {
1384
+ fn new ( mut url : String , name : String ) -> ItemEntry {
1385
+ while url. starts_with ( '/' ) {
1386
+ url. remove ( 0 ) ;
1387
+ }
1388
+ ItemEntry {
1389
+ url,
1390
+ name,
1391
+ }
1392
+ }
1393
+ }
1394
+
1395
+ impl fmt:: Display for ItemEntry {
1396
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1397
+ write ! ( f, "<a href='{}'>{}</a>" , self . url, Escape ( & self . name) )
1398
+ }
1399
+ }
1400
+
1401
+ impl PartialOrd for ItemEntry {
1402
+ fn partial_cmp ( & self , other : & ItemEntry ) -> Option < :: std:: cmp:: Ordering > {
1403
+ Some ( self . cmp ( other) )
1404
+ }
1405
+ }
1406
+
1407
+ impl Ord for ItemEntry {
1408
+ fn cmp ( & self , other : & ItemEntry ) -> :: std:: cmp:: Ordering {
1409
+ self . name . cmp ( & other. name )
1410
+ }
1411
+ }
1412
+
1413
+ #[ derive( Debug ) ]
1414
+ struct AllTypes {
1415
+ structs : HashSet < ItemEntry > ,
1416
+ enums : HashSet < ItemEntry > ,
1417
+ unions : HashSet < ItemEntry > ,
1418
+ primitives : HashSet < ItemEntry > ,
1419
+ traits : HashSet < ItemEntry > ,
1420
+ macros : HashSet < ItemEntry > ,
1421
+ functions : HashSet < ItemEntry > ,
1422
+ typedefs : HashSet < ItemEntry > ,
1423
+ statics : HashSet < ItemEntry > ,
1424
+ constants : HashSet < ItemEntry > ,
1425
+ }
1426
+
1427
+ impl AllTypes {
1428
+ fn new ( ) -> AllTypes {
1429
+ AllTypes {
1430
+ structs : HashSet :: with_capacity ( 100 ) ,
1431
+ enums : HashSet :: with_capacity ( 100 ) ,
1432
+ unions : HashSet :: with_capacity ( 100 ) ,
1433
+ primitives : HashSet :: with_capacity ( 26 ) ,
1434
+ traits : HashSet :: with_capacity ( 100 ) ,
1435
+ macros : HashSet :: with_capacity ( 100 ) ,
1436
+ functions : HashSet :: with_capacity ( 100 ) ,
1437
+ typedefs : HashSet :: with_capacity ( 100 ) ,
1438
+ statics : HashSet :: with_capacity ( 100 ) ,
1439
+ constants : HashSet :: with_capacity ( 100 ) ,
1440
+ }
1441
+ }
1442
+
1443
+ fn append ( & mut self , item_name : String , item_type : & ItemType ) {
1444
+ let mut url: Vec < _ > = item_name. split ( "::" ) . skip ( 1 ) . collect ( ) ;
1445
+ if let Some ( name) = url. pop ( ) {
1446
+ let new_url = format ! ( "{}/{}.{}.html" , url. join( "/" ) , item_type, name) ;
1447
+ url. push ( name) ;
1448
+ let name = url. join ( "::" ) ;
1449
+ match * item_type {
1450
+ ItemType :: Struct => self . structs . insert ( ItemEntry :: new ( new_url, name) ) ,
1451
+ ItemType :: Enum => self . enums . insert ( ItemEntry :: new ( new_url, name) ) ,
1452
+ ItemType :: Union => self . unions . insert ( ItemEntry :: new ( new_url, name) ) ,
1453
+ ItemType :: Primitive => self . primitives . insert ( ItemEntry :: new ( new_url, name) ) ,
1454
+ ItemType :: Trait => self . traits . insert ( ItemEntry :: new ( new_url, name) ) ,
1455
+ ItemType :: Macro => self . macros . insert ( ItemEntry :: new ( new_url, name) ) ,
1456
+ ItemType :: Function => self . functions . insert ( ItemEntry :: new ( new_url, name) ) ,
1457
+ ItemType :: Typedef => self . typedefs . insert ( ItemEntry :: new ( new_url, name) ) ,
1458
+ ItemType :: Static => self . statics . insert ( ItemEntry :: new ( new_url, name) ) ,
1459
+ ItemType :: Constant => self . constants . insert ( ItemEntry :: new ( new_url, name) ) ,
1460
+ _ => true ,
1461
+ } ;
1462
+ }
1463
+ }
1464
+ }
1465
+
1466
+ fn print_entries ( f : & mut fmt:: Formatter , e : & HashSet < ItemEntry > , title : & str ,
1467
+ class : & str ) -> fmt:: Result {
1468
+ if !e. is_empty ( ) {
1469
+ let mut e: Vec < & ItemEntry > = e. iter ( ) . collect ( ) ;
1470
+ e. sort ( ) ;
1471
+ write ! ( f, "<h3 id='{}'>{}</h3><ul class='{} docblock'>{}</ul>" ,
1472
+ title,
1473
+ Escape ( title) ,
1474
+ class,
1475
+ e. iter( ) . map( |s| format!( "<li>{}</li>" , s) ) . collect:: <String >( ) ) ?;
1476
+ }
1477
+ Ok ( ( ) )
1478
+ }
1479
+
1480
+ impl fmt:: Display for AllTypes {
1481
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1482
+ write ! ( f,
1483
+ "<h1 class='fqn'>\
1484
+ <span class='in-band'>List of all items</span>\
1485
+ <span class='out-of-band'>\
1486
+ <span id='render-detail'>\
1487
+ <a id=\" toggle-all-docs\" href=\" javascript:void(0)\" title=\" collapse all docs\" >\
1488
+ [<span class='inner'>−</span>]\
1489
+ </a>\
1490
+ </span>
1491
+ </span>
1492
+ </h1>" ) ?;
1493
+ print_entries ( f, & self . structs , "Structs" , "structs" ) ?;
1494
+ print_entries ( f, & self . enums , "Enums" , "enums" ) ?;
1495
+ print_entries ( f, & self . unions , "Unions" , "unions" ) ?;
1496
+ print_entries ( f, & self . primitives , "Primitives" , "primitives" ) ?;
1497
+ print_entries ( f, & self . traits , "Traits" , "traits" ) ?;
1498
+ print_entries ( f, & self . macros , "Macros" , "macros" ) ?;
1499
+ print_entries ( f, & self . functions , "Functions" , "functions" ) ?;
1500
+ print_entries ( f, & self . typedefs , "Typedefs" , "typedefs" ) ?;
1501
+ print_entries ( f, & self . statics , "Statics" , "statics" ) ?;
1502
+ print_entries ( f, & self . constants , "Constants" , "constants" )
1503
+ }
1504
+ }
1505
+
1376
1506
impl Context {
1377
1507
/// String representation of how to get back to the root path of the 'doc/'
1378
1508
/// folder in terms of a relative URL.
@@ -1414,16 +1544,52 @@ impl Context {
1414
1544
Some ( i) => i,
1415
1545
None => return Ok ( ( ) ) ,
1416
1546
} ;
1547
+ let final_file = self . dst . join ( & krate. name )
1548
+ . join ( "all.html" ) ;
1549
+ let crate_name = krate. name . clone ( ) ;
1417
1550
item. name = Some ( krate. name ) ;
1418
1551
1419
- // Render the crate documentation
1420
- let mut work = vec ! [ ( self , item) ] ;
1552
+ let mut all = AllTypes :: new ( ) ;
1421
1553
1422
- while let Some ( ( mut cx, item) ) = work. pop ( ) {
1423
- cx. item ( item, |cx, item| {
1424
- work. push ( ( cx. clone ( ) , item) )
1425
- } ) ?
1554
+ {
1555
+ // Render the crate documentation
1556
+ let mut work = vec ! [ ( self . clone( ) , item) ] ;
1557
+
1558
+ while let Some ( ( mut cx, item) ) = work. pop ( ) {
1559
+ cx. item ( item, & mut all, |cx, item| {
1560
+ work. push ( ( cx. clone ( ) , item) )
1561
+ } ) ?
1562
+ }
1426
1563
}
1564
+
1565
+ let mut w = BufWriter :: new ( try_err ! ( File :: create( & final_file) , & final_file) ) ;
1566
+ let mut root_path = self . dst . to_str ( ) . expect ( "invalid path" ) . to_owned ( ) ;
1567
+ if !root_path. ends_with ( '/' ) {
1568
+ root_path. push ( '/' ) ;
1569
+ }
1570
+ let page = layout:: Page {
1571
+ title : "List of all items in this crate" ,
1572
+ css_class : "mod" ,
1573
+ root_path : "../" ,
1574
+ description : "List of all items in this crate" ,
1575
+ keywords : BASIC_KEYWORDS ,
1576
+ resource_suffix : & self . shared . resource_suffix ,
1577
+ } ;
1578
+ let sidebar = if let Some ( ref version) = cache ( ) . crate_version {
1579
+ format ! ( "<p class='location'>Crate {}</p>\
1580
+ <div class='block version'>\
1581
+ <p>Version {}</p>\
1582
+ </div>\
1583
+ <a id='all-types' href='index.html'><p>Back to index</p></a>",
1584
+ crate_name, version)
1585
+ } else {
1586
+ String :: new ( )
1587
+ } ;
1588
+ try_err ! ( layout:: render( & mut w, & self . shared. layout,
1589
+ & page, & sidebar, & all,
1590
+ self . shared. css_file_extension. is_some( ) ,
1591
+ & self . shared. themes) ,
1592
+ & final_file) ;
1427
1593
Ok ( ( ) )
1428
1594
}
1429
1595
@@ -1496,8 +1662,8 @@ impl Context {
1496
1662
/// all sub-items which need to be rendered.
1497
1663
///
1498
1664
/// The rendering driver uses this closure to queue up more work.
1499
- fn item < F > ( & mut self , item : clean:: Item , mut f : F ) -> Result < ( ) , Error > where
1500
- F : FnMut ( & mut Context , clean:: Item ) ,
1665
+ fn item < F > ( & mut self , item : clean:: Item , all : & mut AllTypes , mut f : F ) -> Result < ( ) , Error >
1666
+ where F : FnMut ( & mut Context , clean:: Item ) ,
1501
1667
{
1502
1668
// Stripped modules survive the rustdoc passes (i.e. `strip-private`)
1503
1669
// if they contain impls for public types. These modules can also
@@ -1544,7 +1710,7 @@ impl Context {
1544
1710
}
1545
1711
1546
1712
for item in m. items {
1547
- f ( this, item) ;
1713
+ f ( this, item) ;
1548
1714
}
1549
1715
1550
1716
Ok ( ( ) )
@@ -1562,13 +1728,14 @@ impl Context {
1562
1728
let mut dst = try_err ! ( File :: create( & joint_dst) , & joint_dst) ;
1563
1729
try_err ! ( dst. write_all( & buf) , & joint_dst) ;
1564
1730
1731
+ all. append ( full_path ( self , & item) , & item_type) ;
1565
1732
// Redirect from a sane URL using the namespace to Rustdoc's
1566
1733
// URL for the page.
1567
1734
let redir_name = format ! ( "{}.{}.html" , name, item_type. name_space( ) ) ;
1568
1735
let redir_dst = self . dst . join ( redir_name) ;
1569
1736
if let Ok ( redirect_out) = OpenOptions :: new ( ) . create_new ( true )
1570
- . write ( true )
1571
- . open ( & redir_dst) {
1737
+ . write ( true )
1738
+ . open ( & redir_dst) {
1572
1739
let mut redirect_out = BufWriter :: new ( redirect_out) ;
1573
1740
try_err ! ( layout:: redirect( & mut redirect_out, file_name) , & redir_dst) ;
1574
1741
}
@@ -1730,11 +1897,12 @@ impl<'a> fmt::Display for Item<'a> {
1730
1897
version) ?;
1731
1898
}
1732
1899
write ! ( fmt,
1733
- r##"<span id='render-detail'>
1734
- <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
1735
- [<span class='inner'>−</span>]
1736
- </a>
1737
- </span>"## ) ?;
1900
+ "<span id='render-detail'>\
1901
+ <a id=\" toggle-all-docs\" href=\" javascript:void(0)\" \
1902
+ title=\" collapse all docs\" >\
1903
+ [<span class='inner'>−</span>]\
1904
+ </a>\
1905
+ </span>") ?;
1738
1906
1739
1907
// Write `src` tag
1740
1908
//
@@ -3567,33 +3735,34 @@ impl<'a> fmt::Display for Sidebar<'a> {
3567
3735
3568
3736
if it. is_struct ( ) || it. is_trait ( ) || it. is_primitive ( ) || it. is_union ( )
3569
3737
|| it. is_enum ( ) || it. is_mod ( ) || it. is_typedef ( ) {
3570
- write ! ( fmt, "<p class='location'>" ) ?;
3571
- match it. inner {
3572
- clean:: StructItem ( ..) => write ! ( fmt, "Struct " ) ?,
3573
- clean:: TraitItem ( ..) => write ! ( fmt, "Trait " ) ?,
3574
- clean:: PrimitiveItem ( ..) => write ! ( fmt, "Primitive Type " ) ?,
3575
- clean:: UnionItem ( ..) => write ! ( fmt, "Union " ) ?,
3576
- clean:: EnumItem ( ..) => write ! ( fmt, "Enum " ) ?,
3577
- clean:: TypedefItem ( ..) => write ! ( fmt, "Type Definition " ) ?,
3578
- clean:: ForeignTypeItem => write ! ( fmt, "Foreign Type " ) ?,
3579
- clean:: ModuleItem ( ..) => if it. is_crate ( ) {
3580
- write ! ( fmt, "Crate " ) ?;
3581
- } else {
3582
- write ! ( fmt, "Module " ) ?;
3738
+ write ! ( fmt, "<p class='location'>{}{}</p>" ,
3739
+ match it. inner {
3740
+ clean:: StructItem ( ..) => "Struct " ,
3741
+ clean:: TraitItem ( ..) => "Trait " ,
3742
+ clean:: PrimitiveItem ( ..) => "Primitive Type " ,
3743
+ clean:: UnionItem ( ..) => "Union " ,
3744
+ clean:: EnumItem ( ..) => "Enum " ,
3745
+ clean:: TypedefItem ( ..) => "Type Definition " ,
3746
+ clean:: ForeignTypeItem => "Foreign Type " ,
3747
+ clean:: ModuleItem ( ..) => if it. is_crate( ) {
3748
+ "Crate "
3749
+ } else {
3750
+ "Module "
3751
+ } ,
3752
+ _ => "" ,
3583
3753
} ,
3584
- _ => ( ) ,
3585
- }
3586
- write ! ( fmt, "{}" , it. name. as_ref( ) . unwrap( ) ) ?;
3587
- write ! ( fmt, "</p>" ) ?;
3754
+ it. name. as_ref( ) . unwrap( ) ) ?;
3588
3755
}
3589
3756
3590
3757
if it. is_crate ( ) {
3591
3758
if let Some ( ref version) = cache ( ) . crate_version {
3592
3759
write ! ( fmt,
3593
3760
"<div class='block version'>\
3594
3761
<p>Version {}</p>\
3595
- </div>",
3596
- version) ?;
3762
+ </div>
3763
+ <a id='all-types' href='all.html'><p>See all {}'s items</p></a>" ,
3764
+ version,
3765
+ it. name. as_ref( ) . unwrap( ) ) ?;
3597
3766
}
3598
3767
}
3599
3768
0 commit comments