66//! them in the future to instead emit any format desired.
77
88use std:: borrow:: Cow ;
9+ use std:: cell:: Cell ;
910use std:: fmt;
1011
1112use rustc:: hir:: def_id:: DefId ;
@@ -38,8 +39,6 @@ pub struct AsyncSpace(pub hir::IsAsync);
3839pub struct MutableSpace ( pub clean:: Mutability ) ;
3940/// Wrapper struct for emitting type parameter bounds.
4041pub struct GenericBounds < ' a > ( pub & ' a [ clean:: GenericBound ] ) ;
41- /// Wrapper struct for emitting a comma-separated list of items
42- pub struct CommaSep < ' a , T > ( pub & ' a [ T ] ) ;
4342pub struct AbiSpace ( pub Abi ) ;
4443pub struct DefaultSpace ( pub bool ) ;
4544
@@ -68,11 +67,6 @@ pub struct WhereClause<'a>{
6867 pub end_newline : bool ,
6968}
7069
71- pub struct HRef < ' a > {
72- did : DefId ,
73- text : & ' a str ,
74- }
75-
7670impl < ' a > VisSpace < ' a > {
7771 pub fn get ( self ) -> & ' a Option < clean:: Visibility > {
7872 let VisSpace ( v) = self ; v
@@ -91,14 +85,14 @@ impl ConstnessSpace {
9185 }
9286}
9387
94- impl < ' a , T : fmt:: Display > fmt:: Display for CommaSep < ' a , T > {
95- fn fmt ( & self , f : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
96- for ( i, item) in self . 0 . iter ( ) . enumerate ( ) {
88+ fn comma_sep < T : fmt:: Display > ( items : & [ T ] ) -> impl fmt:: Display + ' _ {
89+ display_fn ( move |f| {
90+ for ( i, item) in items . iter ( ) . enumerate ( ) {
9791 if i != 0 { write ! ( f, ", " ) ?; }
9892 fmt:: Display :: fmt ( item, f) ?;
9993 }
10094 Ok ( ( ) )
101- }
95+ } )
10296}
10397
10498impl < ' a > fmt:: Display for GenericBounds < ' a > {
@@ -165,9 +159,9 @@ impl fmt::Display for clean::Generics {
165159 return Ok ( ( ) ) ;
166160 }
167161 if f. alternate ( ) {
168- write ! ( f, "<{:#}>" , CommaSep ( & real_params) )
162+ write ! ( f, "<{:#}>" , comma_sep ( & real_params) )
169163 } else {
170- write ! ( f, "<{}>" , CommaSep ( & real_params) )
164+ write ! ( f, "<{}>" , comma_sep ( & real_params) )
171165 }
172166 }
173167}
@@ -265,9 +259,9 @@ impl fmt::Display for clean::PolyTrait {
265259 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
266260 if !self . generic_params . is_empty ( ) {
267261 if f. alternate ( ) {
268- write ! ( f, "for<{:#}> " , CommaSep ( & self . generic_params) ) ?;
262+ write ! ( f, "for<{:#}> " , comma_sep ( & self . generic_params) ) ?;
269263 } else {
270- write ! ( f, "for<{}> " , CommaSep ( & self . generic_params) ) ?;
264+ write ! ( f, "for<{}> " , comma_sep ( & self . generic_params) ) ?;
271265 }
272266 }
273267 if f. alternate ( ) {
@@ -452,16 +446,15 @@ fn resolved_path(w: &mut fmt::Formatter<'_>, did: DefId, path: &clean::Path,
452446 write ! ( w, "{}{:#}" , & last. name, last. args) ?;
453447 } else {
454448 let path = if use_absolute {
455- match href ( did) {
456- Some ( ( _, _, fqp) ) => {
457- format ! ( "{}::{}" ,
458- fqp[ ..fqp. len( ) - 1 ] . join( "::" ) ,
459- HRef :: new( did, fqp. last( ) . unwrap( ) ) )
460- }
461- None => HRef :: new ( did, & last. name ) . to_string ( ) ,
449+ if let Some ( ( _, _, fqp) ) = href ( did) {
450+ format ! ( "{}::{}" ,
451+ fqp[ ..fqp. len( ) - 1 ] . join( "::" ) ,
452+ anchor( did, fqp. last( ) . unwrap( ) ) )
453+ } else {
454+ last. name . to_string ( )
462455 }
463456 } else {
464- HRef :: new ( did, & last. name ) . to_string ( )
457+ anchor ( did, & last. name ) . to_string ( )
465458 } ;
466459 write ! ( w, "{}{}" , path, last. args) ?;
467460 }
@@ -513,35 +506,30 @@ fn primitive_link(f: &mut fmt::Formatter<'_>,
513506}
514507
515508/// Helper to render type parameters
516- fn tybounds ( w : & mut fmt:: Formatter < ' _ > ,
517- param_names : & Option < Vec < clean:: GenericBound > > ) -> fmt:: Result {
518- match * param_names {
519- Some ( ref params) => {
520- for param in params {
521- write ! ( w, " + " ) ?;
522- fmt:: Display :: fmt ( param, w) ?;
509+ fn tybounds ( param_names : & Option < Vec < clean:: GenericBound > > ) -> impl fmt:: Display + ' _ {
510+ display_fn ( move |f| {
511+ match * param_names {
512+ Some ( ref params) => {
513+ for param in params {
514+ write ! ( f, " + " ) ?;
515+ fmt:: Display :: fmt ( param, f) ?;
516+ }
517+ Ok ( ( ) )
523518 }
524- Ok ( ( ) )
519+ None => Ok ( ( ) )
525520 }
526- None => Ok ( ( ) )
527- }
528- }
529-
530- impl < ' a > HRef < ' a > {
531- pub fn new ( did : DefId , text : & ' a str ) -> HRef < ' a > {
532- HRef { did : did, text : text }
533- }
521+ } )
534522}
535523
536- impl < ' a > fmt:: Display for HRef < ' a > {
537- fn fmt ( & self , f : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
538- if let Some ( ( url, short_ty, fqp) ) = href ( self . did ) {
524+ pub fn anchor ( did : DefId , text : & str ) -> impl fmt:: Display + ' _ {
525+ display_fn ( move |f| {
526+ if let Some ( ( url, short_ty, fqp) ) = href ( did) {
539527 write ! ( f, r#"<a class="{}" href="{}" title="{} {}">{}</a>"# ,
540- short_ty, url, short_ty, fqp. join( "::" ) , self . text)
528+ short_ty, url, short_ty, fqp. join( "::" ) , text)
541529 } else {
542- write ! ( f, "{}" , self . text)
530+ write ! ( f, "{}" , text)
543531 }
544- }
532+ } )
545533}
546534
547535fn fmt_type ( t : & clean:: Type , f : & mut fmt:: Formatter < ' _ > , use_absolute : bool ) -> fmt:: Result {
@@ -555,7 +543,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
555543 }
556544 // Paths like `T::Output` and `Self::Output` should be rendered with all segments.
557545 resolved_path ( f, did, path, is_generic, use_absolute) ?;
558- tybounds ( f , param_names )
546+ fmt :: Display :: fmt ( & tybounds ( param_names ) , f )
559547 }
560548 clean:: Infer => write ! ( f, "_" ) ,
561549 clean:: Primitive ( prim) => primitive_link ( f, prim, prim. as_str ( ) ) ,
@@ -564,12 +552,12 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
564552 write ! ( f, "{}{:#}fn{:#}{:#}" ,
565553 UnsafetySpace ( decl. unsafety) ,
566554 AbiSpace ( decl. abi) ,
567- CommaSep ( & decl. generic_params) ,
555+ comma_sep ( & decl. generic_params) ,
568556 decl. decl)
569557 } else {
570558 write ! ( f, "{}{}" , UnsafetySpace ( decl. unsafety) , AbiSpace ( decl. abi) ) ?;
571559 primitive_link ( f, PrimitiveType :: Fn , "fn" ) ?;
572- write ! ( f, "{}{}" , CommaSep ( & decl. generic_params) , decl. decl)
560+ write ! ( f, "{}{}" , comma_sep ( & decl. generic_params) , decl. decl)
573561 }
574562 }
575563 clean:: Tuple ( ref typs) => {
@@ -583,7 +571,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
583571 }
584572 many => {
585573 primitive_link ( f, PrimitiveType :: Tuple , "(" ) ?;
586- fmt:: Display :: fmt ( & CommaSep ( many) , f) ?;
574+ fmt:: Display :: fmt ( & comma_sep ( many) , f) ?;
587575 primitive_link ( f, PrimitiveType :: Tuple , ")" )
588576 }
589577 }
@@ -1063,3 +1051,19 @@ impl fmt::Display for DefaultSpace {
10631051 }
10641052 }
10651053}
1054+
1055+ crate fn display_fn (
1056+ f : impl FnOnce ( & mut fmt:: Formatter < ' _ > ) -> fmt:: Result ,
1057+ ) -> impl fmt:: Display {
1058+ WithFormatter ( Cell :: new ( Some ( f) ) )
1059+ }
1060+
1061+ struct WithFormatter < F > ( Cell < Option < F > > ) ;
1062+
1063+ impl < F > fmt:: Display for WithFormatter < F >
1064+ where F : FnOnce ( & mut fmt:: Formatter < ' _ > ) -> fmt:: Result ,
1065+ {
1066+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1067+ ( self . 0 . take ( ) ) . unwrap ( ) ( f)
1068+ }
1069+ }
0 commit comments