10
10
11
11
//! Format attributes and meta items.
12
12
13
+ use config:: IndentStyle ;
13
14
use config:: lists:: * ;
14
15
use syntax:: ast;
15
16
use syntax:: codemap:: Span ;
@@ -183,17 +184,35 @@ fn has_newlines_before_after_comment(comment: &str) -> (&str, &str) {
183
184
( if mlb { "\n " } else { "" } , if mla { "\n " } else { "" } )
184
185
}
185
186
187
+ fn allow_mixed_tactic_for_nested_metaitem_list ( list : & [ ast:: NestedMetaItem ] ) -> bool {
188
+ list. iter ( ) . all ( |nested_metaitem| {
189
+ if let ast:: NestedMetaItemKind :: MetaItem ( ref inner_metaitem) = nested_metaitem. node {
190
+ match inner_metaitem. node {
191
+ ast:: MetaItemKind :: List ( ..) | ast:: MetaItemKind :: NameValue ( ..) => false ,
192
+ _ => true ,
193
+ }
194
+ } else {
195
+ true
196
+ }
197
+ } )
198
+ }
199
+
186
200
impl Rewrite for ast:: MetaItem {
187
201
fn rewrite ( & self , context : & RewriteContext , shape : Shape ) -> Option < String > {
188
202
Some ( match self . node {
189
203
ast:: MetaItemKind :: Word => String :: from ( & * self . name . as_str ( ) ) ,
190
204
ast:: MetaItemKind :: List ( ref list) => {
191
205
let name = self . name . as_str ( ) ;
192
- // 1 = `(`, 2 = `]` and `)`
193
- let item_shape = shape
194
- . visual_indent ( 0 )
195
- . shrink_left ( name. len ( ) + 1 )
196
- . and_then ( |s| s. sub_width ( 2 ) ) ?;
206
+ let item_shape = match context. config . indent_style ( ) {
207
+ IndentStyle :: Block => shape
208
+ . block_indent ( context. config . tab_spaces ( ) )
209
+ . with_max_width ( context. config ) ,
210
+ // 1 = `(`, 2 = `]` and `)`
211
+ IndentStyle :: Visual => shape
212
+ . visual_indent ( 0 )
213
+ . shrink_left ( name. len ( ) + 1 )
214
+ . and_then ( |s| s. sub_width ( 2 ) ) ?,
215
+ } ;
197
216
let items = itemize_list (
198
217
context. snippet_provider ,
199
218
list. iter ( ) ,
@@ -207,8 +226,18 @@ impl Rewrite for ast::MetaItem {
207
226
false ,
208
227
) ;
209
228
let item_vec = items. collect :: < Vec < _ > > ( ) ;
229
+ let tactic = if allow_mixed_tactic_for_nested_metaitem_list ( list) {
230
+ DefinitiveListTactic :: Mixed
231
+ } else {
232
+ :: lists:: definitive_tactic (
233
+ & item_vec,
234
+ ListTactic :: HorizontalVertical ,
235
+ :: lists:: Separator :: Comma ,
236
+ item_shape. width ,
237
+ )
238
+ } ;
210
239
let fmt = ListFormatting {
211
- tactic : DefinitiveListTactic :: Mixed ,
240
+ tactic,
212
241
separator : "," ,
213
242
trailing_separator : SeparatorTactic :: Never ,
214
243
separator_place : SeparatorPlace :: Back ,
@@ -217,7 +246,17 @@ impl Rewrite for ast::MetaItem {
217
246
preserve_newline : false ,
218
247
config : context. config ,
219
248
} ;
220
- format ! ( "{}({})" , name, write_list( & item_vec, & fmt) ?)
249
+ let item_str = write_list ( & item_vec, & fmt) ?;
250
+ let one_line_budget = shape. offset_left ( name. len ( ) ) ?. sub_width ( 2 ) ?. width ;
251
+ if context. config . indent_style ( ) == IndentStyle :: Visual
252
+ || ( !item_str. contains ( '\n' ) && item_str. len ( ) <= one_line_budget)
253
+ {
254
+ format ! ( "{}({})" , name, item_str)
255
+ } else {
256
+ let indent = shape. indent . to_string_with_newline ( context. config ) ;
257
+ let nested_indent = item_shape. indent . to_string_with_newline ( context. config ) ;
258
+ format ! ( "{}({}{}{})" , name, nested_indent, item_str, indent)
259
+ }
221
260
}
222
261
ast:: MetaItemKind :: NameValue ( ref literal) => {
223
262
let name = self . name . as_str ( ) ;
0 commit comments