@@ -37,7 +37,7 @@ pub use self::ExternalLocation::*;
37
37
use std:: ascii:: AsciiExt ;
38
38
use std:: cell:: RefCell ;
39
39
use std:: cmp:: Ordering ;
40
- use std:: collections:: BTreeMap ;
40
+ use std:: collections:: { BTreeMap , HashSet } ;
41
41
use std:: default:: Default ;
42
42
use std:: error;
43
43
use std:: fmt:: { self , Display , Formatter , Write as FmtWrite } ;
@@ -3207,12 +3207,37 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
3207
3207
}
3208
3208
}
3209
3209
3210
+ fn should_render_item ( item : & clean:: Item , deref_mut_ : bool ) -> bool {
3211
+ let self_type_opt = match item. inner {
3212
+ clean:: MethodItem ( ref method) => method. decl . self_type ( ) ,
3213
+ clean:: TyMethodItem ( ref method) => method. decl . self_type ( ) ,
3214
+ _ => None
3215
+ } ;
3216
+
3217
+ if let Some ( self_ty) = self_type_opt {
3218
+ let ( by_mut_ref, by_box) = match self_ty {
3219
+ SelfTy :: SelfBorrowed ( _, mutability) |
3220
+ SelfTy :: SelfExplicit ( clean:: BorrowedRef { mutability, .. } ) => {
3221
+ ( mutability == Mutability :: Mutable , false )
3222
+ } ,
3223
+ SelfTy :: SelfExplicit ( clean:: ResolvedPath { did, .. } ) => {
3224
+ ( false , Some ( did) == cache ( ) . owned_box_did )
3225
+ } ,
3226
+ _ => ( false , false ) ,
3227
+ } ;
3228
+
3229
+ ( deref_mut_ || !by_mut_ref) && !by_box
3230
+ } else {
3231
+ false
3232
+ }
3233
+ }
3234
+
3210
3235
fn render_impl ( w : & mut fmt:: Formatter , cx : & Context , i : & Impl , link : AssocItemLink ,
3211
3236
render_mode : RenderMode , outer_version : Option < & str > ,
3212
3237
show_def_docs : bool ) -> fmt:: Result {
3213
3238
if render_mode == RenderMode :: Normal {
3214
3239
let id = derive_id ( match i. inner_impl ( ) . trait_ {
3215
- Some ( ref t) => format ! ( "impl-{}" , Escape ( & format!( "{:#}" , t) ) ) ,
3240
+ Some ( ref t) => format ! ( "impl-{}" , small_url_encode ( & format!( "{:#}" , t) ) ) ,
3216
3241
None => "impl" . to_string ( ) ,
3217
3242
} ) ;
3218
3243
write ! ( w, "<h3 id='{}' class='impl'><span class='in-band'><code>{}</code>" ,
@@ -3244,30 +3269,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
3244
3269
3245
3270
let render_method_item: bool = match render_mode {
3246
3271
RenderMode :: Normal => true ,
3247
- RenderMode :: ForDeref { mut_ : deref_mut_ } => {
3248
- let self_type_opt = match item. inner {
3249
- clean:: MethodItem ( ref method) => method. decl . self_type ( ) ,
3250
- clean:: TyMethodItem ( ref method) => method. decl . self_type ( ) ,
3251
- _ => None
3252
- } ;
3253
-
3254
- if let Some ( self_ty) = self_type_opt {
3255
- let ( by_mut_ref, by_box) = match self_ty {
3256
- SelfTy :: SelfBorrowed ( _, mutability) |
3257
- SelfTy :: SelfExplicit ( clean:: BorrowedRef { mutability, .. } ) => {
3258
- ( mutability == Mutability :: Mutable , false )
3259
- } ,
3260
- SelfTy :: SelfExplicit ( clean:: ResolvedPath { did, .. } ) => {
3261
- ( false , Some ( did) == cache ( ) . owned_box_did )
3262
- } ,
3263
- _ => ( false , false ) ,
3264
- } ;
3265
-
3266
- ( deref_mut_ || !by_mut_ref) && !by_box
3267
- } else {
3268
- false
3269
- }
3270
- } ,
3272
+ RenderMode :: ForDeref { mut_ : deref_mut_ } => should_render_item ( & item, deref_mut_) ,
3271
3273
} ;
3272
3274
3273
3275
match item. inner {
@@ -3514,12 +3516,48 @@ impl<'a> fmt::Display for Sidebar<'a> {
3514
3516
}
3515
3517
}
3516
3518
3519
+ fn get_methods ( i : & clean:: Impl , for_deref : bool ) -> Vec < String > {
3520
+ i. items . iter ( ) . filter_map ( |item| {
3521
+ match item. name {
3522
+ // Maybe check with clean::Visibility::Public as well?
3523
+ Some ( ref name) if !name. is_empty ( ) && item. visibility . is_some ( ) && item. is_method ( ) => {
3524
+ if !for_deref || should_render_item ( item, false ) {
3525
+ Some ( format ! ( "<a href=\" #method.{name}\" >{name}</a>" , name = name) )
3526
+ } else {
3527
+ None
3528
+ }
3529
+ }
3530
+ _ => None ,
3531
+ }
3532
+ } ) . collect :: < Vec < _ > > ( )
3533
+ }
3534
+
3535
+ // The point is to url encode any potential character from a type with genericity.
3536
+ fn small_url_encode ( s : & str ) -> String {
3537
+ s. replace ( "<" , "%3C" )
3538
+ . replace ( ">" , "%3E" )
3539
+ . replace ( " " , "%20" )
3540
+ . replace ( "?" , "%3F" )
3541
+ . replace ( "'" , "%27" )
3542
+ . replace ( "&" , "%26" )
3543
+ . replace ( "," , "%2C" )
3544
+ . replace ( ":" , "%3A" )
3545
+ . replace ( ";" , "%3B" )
3546
+ . replace ( "[" , "%5B" )
3547
+ . replace ( "]" , "%5D" )
3548
+ }
3549
+
3517
3550
fn sidebar_assoc_items ( it : & clean:: Item ) -> String {
3518
3551
let mut out = String :: new ( ) ;
3519
3552
let c = cache ( ) ;
3520
3553
if let Some ( v) = c. impls . get ( & it. def_id ) {
3521
- if v. iter ( ) . any ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) {
3522
- out. push_str ( "<li><a href=\" #methods\" >Methods</a></li>" ) ;
3554
+ let ret = v. iter ( )
3555
+ . filter ( |i| i. inner_impl ( ) . trait_ . is_none ( ) )
3556
+ . flat_map ( |i| get_methods ( i. inner_impl ( ) , false ) )
3557
+ . collect :: < String > ( ) ;
3558
+ if !ret. is_empty ( ) {
3559
+ out. push_str ( & format ! ( "<a class=\" sidebar-title\" href=\" #methods\" >Methods\
3560
+ </a><div class=\" sidebar-links\" >{}</div>", ret) ) ;
3523
3561
}
3524
3562
3525
3563
if v. iter ( ) . any ( |i| i. inner_impl ( ) . trait_ . is_some ( ) ) {
@@ -3535,16 +3573,40 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
3535
3573
let inner_impl = target. def_id ( ) . or ( target. primitive_type ( ) . and_then ( |prim| {
3536
3574
c. primitive_locations . get ( & prim) . cloned ( )
3537
3575
} ) ) . and_then ( |did| c. impls . get ( & did) ) ;
3538
- if inner_impl . is_some ( ) {
3539
- out. push_str ( "<li><a href=\" #deref-methods\" >" ) ;
3576
+ if let Some ( impls ) = inner_impl {
3577
+ out. push_str ( "<a class= \" sidebar-title \" href=\" #deref-methods\" >" ) ;
3540
3578
out. push_str ( & format ! ( "Methods from {:#}<Target={:#}>" ,
3541
- impl_. inner_impl( ) . trait_. as_ref( ) . unwrap( ) ,
3542
- target) ) ;
3543
- out. push_str ( "</a></li>" ) ;
3579
+ impl_. inner_impl( ) . trait_. as_ref( ) . unwrap( ) ,
3580
+ target) ) ;
3581
+ out. push_str ( "</a>" ) ;
3582
+ let ret = impls. iter ( )
3583
+ . filter ( |i| i. inner_impl ( ) . trait_ . is_none ( ) )
3584
+ . flat_map ( |i| get_methods ( i. inner_impl ( ) , true ) )
3585
+ . collect :: < String > ( ) ;
3586
+ out. push_str ( & format ! ( "<div class=\" sidebar-links\" >{}</div>" , ret) ) ;
3544
3587
}
3545
3588
}
3546
3589
}
3547
- out. push_str ( "<li><a href=\" #implementations\" >Trait Implementations</a></li>" ) ;
3590
+ let mut links = HashSet :: new ( ) ;
3591
+ let ret = v. iter ( )
3592
+ . filter_map ( |i| if let Some ( ref i) = i. inner_impl ( ) . trait_ {
3593
+ let out = format ! ( "{:#}" , i) . replace ( "<" , "<" ) . replace ( ">" , ">" ) ;
3594
+ let encoded = small_url_encode ( & format ! ( "{:#}" , i) ) ;
3595
+ let generated = format ! ( "<a href=\" #impl-{}\" >{}</a>" , encoded, out) ;
3596
+ if !links. contains ( & generated) && links. insert ( generated. clone ( ) ) {
3597
+ Some ( generated)
3598
+ } else {
3599
+ None
3600
+ }
3601
+ } else {
3602
+ None
3603
+ } )
3604
+ . collect :: < String > ( ) ;
3605
+ if !ret. is_empty ( ) {
3606
+ out. push_str ( "<a class=\" sidebar-title\" href=\" #implementations\" >\
3607
+ Trait Implementations</a>") ;
3608
+ out. push_str ( & format ! ( "<div class=\" sidebar-links\" >{}</div>" , ret) ) ;
3609
+ }
3548
3610
}
3549
3611
}
3550
3612
@@ -3565,7 +3627,7 @@ fn sidebar_struct(fmt: &mut fmt::Formatter, it: &clean::Item,
3565
3627
sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
3566
3628
3567
3629
if !sidebar. is_empty ( ) {
3568
- write ! ( fmt, "<div class=\" block items\" ><ul>{}</ul> </div>" , sidebar) ?;
3630
+ write ! ( fmt, "<div class=\" block items\" >{} </div>" , sidebar) ?;
3569
3631
}
3570
3632
Ok ( ( ) )
3571
3633
}
@@ -3592,8 +3654,6 @@ fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item,
3592
3654
sidebar. push_str ( "<li><a href=\" #provided-methods\" >Provided Methods</a></li>" ) ;
3593
3655
}
3594
3656
3595
- sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
3596
-
3597
3657
let c = cache ( ) ;
3598
3658
3599
3659
if let Some ( implementors) = c. implementors . get ( & it. def_id ) {
@@ -3607,15 +3667,17 @@ fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item,
3607
3667
3608
3668
sidebar. push_str ( "<li><a href=\" #implementors\" >Implementors</a></li>" ) ;
3609
3669
3610
- write ! ( fmt, "<div class=\" block items\" ><ul>{}</ul></div>" , sidebar)
3670
+ sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
3671
+
3672
+ write ! ( fmt, "<div class=\" block items\" >{}</div>" , sidebar)
3611
3673
}
3612
3674
3613
3675
fn sidebar_primitive ( fmt : & mut fmt:: Formatter , it : & clean:: Item ,
3614
3676
_p : & clean:: PrimitiveType ) -> fmt:: Result {
3615
3677
let sidebar = sidebar_assoc_items ( it) ;
3616
3678
3617
3679
if !sidebar. is_empty ( ) {
3618
- write ! ( fmt, "<div class=\" block items\" ><ul>{}</ul> </div>" , sidebar) ?;
3680
+ write ! ( fmt, "<div class=\" block items\" >{} </div>" , sidebar) ?;
3619
3681
}
3620
3682
Ok ( ( ) )
3621
3683
}
@@ -3625,7 +3687,7 @@ fn sidebar_typedef(fmt: &mut fmt::Formatter, it: &clean::Item,
3625
3687
let sidebar = sidebar_assoc_items ( it) ;
3626
3688
3627
3689
if !sidebar. is_empty ( ) {
3628
- write ! ( fmt, "<div class=\" block items\" ><ul>{}</ul> </div>" , sidebar) ?;
3690
+ write ! ( fmt, "<div class=\" block items\" >{} </div>" , sidebar) ?;
3629
3691
}
3630
3692
Ok ( ( ) )
3631
3693
}
@@ -3642,7 +3704,7 @@ fn sidebar_union(fmt: &mut fmt::Formatter, it: &clean::Item,
3642
3704
sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
3643
3705
3644
3706
if !sidebar. is_empty ( ) {
3645
- write ! ( fmt, "<div class=\" block items\" ><ul>{}</ul> </div>" , sidebar) ?;
3707
+ write ! ( fmt, "<div class=\" block items\" >{} </div>" , sidebar) ?;
3646
3708
}
3647
3709
Ok ( ( ) )
3648
3710
}
@@ -3658,7 +3720,7 @@ fn sidebar_enum(fmt: &mut fmt::Formatter, it: &clean::Item,
3658
3720
sidebar. push_str ( & sidebar_assoc_items ( it) ) ;
3659
3721
3660
3722
if !sidebar. is_empty ( ) {
3661
- write ! ( fmt, "<div class=\" block items\" ><ul>{}</ul> </div>" , sidebar) ?;
3723
+ write ! ( fmt, "<div class=\" block items\" >{} </div>" , sidebar) ?;
3662
3724
}
3663
3725
Ok ( ( ) )
3664
3726
}
0 commit comments