@@ -9,7 +9,6 @@ use rustc_middle::middle::stability;
9
9
use rustc_middle:: ty:: { self , TyCtxt } ;
10
10
use rustc_span:: hygiene:: MacroKind ;
11
11
use rustc_span:: symbol:: { kw, sym, Symbol } ;
12
- use std:: borrow:: Borrow ;
13
12
use std:: cell:: { RefCell , RefMut } ;
14
13
use std:: cmp:: Ordering ;
15
14
use std:: fmt;
@@ -40,6 +39,110 @@ use crate::html::{highlight, static_files};
40
39
use askama:: Template ;
41
40
use itertools:: Itertools ;
42
41
42
+ /// Generates an Askama template struct for rendering items with common methods.
43
+ ///
44
+ /// Usage:
45
+ /// ```ignore (illustrative)
46
+ /// item_template!(
47
+ /// #[template(path = "<template.html>", /* additional values */)]
48
+ /// /* additional meta items */
49
+ /// struct MyItem<'a, 'cx> {
50
+ /// cx: RefCell<&'a mut Context<'cx>>,
51
+ /// it: &'a clean::Item,
52
+ /// /* additional fields */
53
+ /// },
54
+ /// methods = [ /* method names (comma separated; refer to macro definition of `item_template_methods!()`) */ ]
55
+ /// )
56
+ /// ```
57
+ ///
58
+ /// NOTE: ensure that the generic lifetimes (`'a`, `'cx`) and
59
+ /// required fields (`cx`, `it`) are identical (in terms of order and definition).
60
+ macro_rules! item_template {
61
+ (
62
+ $( #[ $meta: meta] ) *
63
+ struct $name: ident<' a, ' cx> {
64
+ cx: RefCell <& ' a mut Context <' cx>>,
65
+ it: & ' a clean:: Item ,
66
+ $( $field_name: ident: $field_ty: ty) ,* ,
67
+ } ,
68
+ methods = [ $( $methods: tt) ,* $( , ) ?]
69
+ ) => {
70
+ #[ derive( Template ) ]
71
+ $( #[ $meta] ) *
72
+ struct $name<' a, ' cx> {
73
+ cx: RefCell <& ' a mut Context <' cx>>,
74
+ it: & ' a clean:: Item ,
75
+ $( $field_name: $field_ty) ,*
76
+ }
77
+
78
+ impl <' a, ' cx: ' a> ItemTemplate <' a, ' cx> for $name<' a, ' cx> {
79
+ fn item_and_mut_cx( & self ) -> ( & ' a clean:: Item , RefMut <' _, & ' a mut Context <' cx>>) {
80
+ ( & self . it, self . cx. borrow_mut( ) )
81
+ }
82
+ }
83
+
84
+ impl <' a, ' cx: ' a> $name<' a, ' cx> {
85
+ item_template_methods!( $( $methods) * ) ;
86
+ }
87
+ } ;
88
+ }
89
+
90
+ /// Implement common methods for item template structs generated by `item_template!()`.
91
+ ///
92
+ /// NOTE: this macro is intended to be used only by `item_template!()`.
93
+ macro_rules! item_template_methods {
94
+ ( ) => { } ;
95
+ ( document $( $rest: tt) * ) => {
96
+ fn document<' b>( & ' b self ) -> impl fmt:: Display + Captures <' a> + ' b + Captures <' cx> {
97
+ display_fn( move |f| {
98
+ let ( item, mut cx) = self . item_and_mut_cx( ) ;
99
+ let v = document( * cx, item, None , HeadingOffset :: H2 ) ;
100
+ write!( f, "{v}" )
101
+ } )
102
+ }
103
+ item_template_methods!( $( $rest) * ) ;
104
+ } ;
105
+ ( document_type_layout $( $rest: tt) * ) => {
106
+ fn document_type_layout<' b>( & ' b self ) -> impl fmt:: Display + Captures <' a> + ' b + Captures <' cx> {
107
+ display_fn( move |f| {
108
+ let ( item, cx) = self . item_and_mut_cx( ) ;
109
+ let def_id = item. item_id. expect_def_id( ) ;
110
+ let v = document_type_layout( * cx, def_id) ;
111
+ write!( f, "{v}" )
112
+ } )
113
+ }
114
+ item_template_methods!( $( $rest) * ) ;
115
+ } ;
116
+ ( render_attributes_in_pre $( $rest: tt) * ) => {
117
+ fn render_attributes_in_pre<' b>( & ' b self ) -> impl fmt:: Display + Captures <' a> + ' b + Captures <' cx> {
118
+ display_fn( move |f| {
119
+ let ( item, cx) = self . item_and_mut_cx( ) ;
120
+ let tcx = cx. tcx( ) ;
121
+ let v = render_attributes_in_pre( item, "" , tcx) ;
122
+ write!( f, "{v}" )
123
+ } )
124
+ }
125
+ item_template_methods!( $( $rest) * ) ;
126
+ } ;
127
+ ( render_assoc_items $( $rest: tt) * ) => {
128
+ fn render_assoc_items<' b>( & ' b self ) -> impl fmt:: Display + Captures <' a> + ' b + Captures <' cx> {
129
+ display_fn( move |f| {
130
+ let ( item, mut cx) = self . item_and_mut_cx( ) ;
131
+ let def_id = item. item_id. expect_def_id( ) ;
132
+ let v = render_assoc_items( * cx, item, def_id, AssocItemRender :: All , None ) ;
133
+ write!( f, "{v}" )
134
+ } )
135
+ }
136
+ item_template_methods!( $( $rest) * ) ;
137
+ } ;
138
+ ( $method: ident $( $rest: tt) * ) => {
139
+ compile_error!( concat!( "unknown method: " , stringify!( $method) ) ) ;
140
+ } ;
141
+ ( $token: tt $( $rest: tt) * ) => {
142
+ compile_error!( concat!( "unexpected token: " , stringify!( $token) ) ) ;
143
+ } ;
144
+ }
145
+
43
146
const ITEM_TABLE_OPEN : & str = "<ul class=\" item-table\" >" ;
44
147
const ITEM_TABLE_CLOSE : & str = "</ul>" ;
45
148
const ITEM_TABLE_ROW_OPEN : & str = "<li>" ;
@@ -222,49 +325,6 @@ trait ItemTemplate<'a, 'cx: 'a>: askama::Template + fmt::Display {
222
325
fn item_and_mut_cx ( & self ) -> ( & ' a clean:: Item , RefMut < ' _ , & ' a mut Context < ' cx > > ) ;
223
326
}
224
327
225
- fn item_template_document < ' a : ' b , ' b , ' cx : ' a > (
226
- templ : & ' b impl ItemTemplate < ' a , ' cx > ,
227
- ) -> impl fmt:: Display + Captures < ' a > + ' b + Captures < ' cx > {
228
- display_fn ( move |f| {
229
- let ( item, mut cx) = templ. item_and_mut_cx ( ) ;
230
- let v = document ( * cx, item, None , HeadingOffset :: H2 ) ;
231
- write ! ( f, "{v}" )
232
- } )
233
- }
234
-
235
- fn item_template_document_type_layout < ' a : ' b , ' b , ' cx : ' a > (
236
- templ : & ' b impl ItemTemplate < ' a , ' cx > ,
237
- ) -> impl fmt:: Display + Captures < ' a > + ' b + Captures < ' cx > {
238
- display_fn ( move |f| {
239
- let ( item, cx) = templ. item_and_mut_cx ( ) ;
240
- let def_id = item. item_id . expect_def_id ( ) ;
241
- let v = document_type_layout ( * cx, def_id) ;
242
- write ! ( f, "{v}" )
243
- } )
244
- }
245
-
246
- fn item_template_render_attributes_in_pre < ' a : ' b , ' b , ' cx : ' a > (
247
- templ : & ' b impl ItemTemplate < ' a , ' cx > ,
248
- ) -> impl fmt:: Display + Captures < ' a > + ' b + Captures < ' cx > {
249
- display_fn ( move |f| {
250
- let ( item, cx) = templ. item_and_mut_cx ( ) ;
251
- let tcx = cx. tcx ( ) ;
252
- let v = render_attributes_in_pre ( item, "" , tcx) ;
253
- write ! ( f, "{v}" )
254
- } )
255
- }
256
-
257
- fn item_template_render_assoc_items < ' a : ' b , ' b , ' cx : ' a > (
258
- templ : & ' b impl ItemTemplate < ' a , ' cx > ,
259
- ) -> impl fmt:: Display + Captures < ' a > + ' b + Captures < ' cx > {
260
- display_fn ( move |f| {
261
- let ( item, mut cx) = templ. item_and_mut_cx ( ) ;
262
- let def_id = item. item_id . expect_def_id ( ) ;
263
- let v = render_assoc_items ( * cx, item, def_id, AssocItemRender :: All , None ) ;
264
- write ! ( f, "{v}" )
265
- } )
266
- }
267
-
268
328
fn item_module ( w : & mut Buffer , cx : & mut Context < ' _ > , item : & clean:: Item , items : & [ clean:: Item ] ) {
269
329
write ! ( w, "{}" , document( cx, item, None , HeadingOffset :: H2 ) ) ;
270
330
@@ -1200,19 +1260,15 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea
1200
1260
}
1201
1261
1202
1262
fn item_union ( w : & mut Buffer , cx : & mut Context < ' _ > , it : & clean:: Item , s : & clean:: Union ) {
1203
- #[ derive( Template ) ]
1204
- #[ template( path = "item_union.html" ) ]
1205
- struct ItemUnion < ' a , ' cx > {
1206
- cx : RefCell < & ' a mut Context < ' cx > > ,
1207
- it : & ' a clean:: Item ,
1208
- s : & ' a clean:: Union ,
1209
- }
1210
-
1211
- impl < ' a , ' cx : ' a > ItemTemplate < ' a , ' cx > for ItemUnion < ' a , ' cx > {
1212
- fn item_and_mut_cx ( & self ) -> ( & ' a clean:: Item , RefMut < ' _ , & ' a mut Context < ' cx > > ) {
1213
- ( self . it , self . cx . borrow_mut ( ) )
1214
- }
1215
- }
1263
+ item_template ! (
1264
+ #[ template( path = "item_union.html" ) ]
1265
+ struct ItemUnion <' a, ' cx> {
1266
+ cx: RefCell <& ' a mut Context <' cx>>,
1267
+ it: & ' a clean:: Item ,
1268
+ s: & ' a clean:: Union ,
1269
+ } ,
1270
+ methods = [ document, document_type_layout, render_attributes_in_pre, render_assoc_items]
1271
+ ) ;
1216
1272
1217
1273
impl < ' a , ' cx : ' a > ItemUnion < ' a , ' cx > {
1218
1274
fn render_union < ' b > ( & ' b self ) -> impl fmt:: Display + Captures < ' a > + ' b + Captures < ' cx > {
@@ -1222,6 +1278,7 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
1222
1278
write ! ( f, "{v}" )
1223
1279
} )
1224
1280
}
1281
+
1225
1282
fn document_field < ' b > (
1226
1283
& ' b self ,
1227
1284
field : & ' a clean:: Item ,
@@ -1232,10 +1289,12 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
1232
1289
write ! ( f, "{v}" )
1233
1290
} )
1234
1291
}
1292
+
1235
1293
fn stability_field ( & self , field : & clean:: Item ) -> Option < String > {
1236
1294
let cx = self . cx . borrow ( ) ;
1237
1295
field. stability_class ( cx. tcx ( ) )
1238
1296
}
1297
+
1239
1298
fn print_ty < ' b > (
1240
1299
& ' b self ,
1241
1300
ty : & ' a clean:: Type ,
0 commit comments