@@ -151,20 +151,37 @@ fn create_struct_def(
151
151
field_list : & Either < ast:: RecordFieldList , ast:: TupleFieldList > ,
152
152
visibility : Option < ast:: Visibility > ,
153
153
) -> ast:: Struct {
154
- let pub_vis = Some ( make:: visibility_pub ( ) ) ;
154
+ let pub_vis = make:: visibility_pub ( ) ;
155
+
156
+ let insert_pub = |node : & ' _ SyntaxNode | {
157
+ let pub_vis = pub_vis. clone_for_update ( ) ;
158
+ ted:: insert ( ted:: Position :: before ( node) , pub_vis. syntax ( ) ) ;
159
+ } ;
160
+
161
+ // for fields without any existing visibility, use pub visibility
155
162
let field_list = match field_list {
156
163
Either :: Left ( field_list) => {
157
- make:: record_field_list ( field_list. fields ( ) . flat_map ( |field| {
158
- Some ( make:: record_field ( pub_vis. clone ( ) , field. name ( ) ?, field. ty ( ) ?) )
159
- } ) )
160
- . into ( )
164
+ let field_list = field_list. clone_for_update ( ) ;
165
+
166
+ field_list
167
+ . fields ( )
168
+ . filter ( |field| field. visibility ( ) . is_none ( ) )
169
+ . filter_map ( |field| field. name ( ) )
170
+ . for_each ( |it| insert_pub ( it. syntax ( ) ) ) ;
171
+
172
+ field_list. into ( )
161
173
}
162
- Either :: Right ( field_list) => make:: tuple_field_list (
174
+ Either :: Right ( field_list) => {
175
+ let field_list = field_list. clone_for_update ( ) ;
176
+
163
177
field_list
164
178
. fields ( )
165
- . flat_map ( |field| Some ( make:: tuple_field ( pub_vis. clone ( ) , field. ty ( ) ?) ) ) ,
166
- )
167
- . into ( ) ,
179
+ . filter ( |field| field. visibility ( ) . is_none ( ) )
180
+ . filter_map ( |field| field. ty ( ) )
181
+ . for_each ( |it| insert_pub ( it. syntax ( ) ) ) ;
182
+
183
+ field_list. into ( )
184
+ }
168
185
} ;
169
186
170
187
make:: struct_ ( visibility, variant_name, None , field_list) . clone_for_update ( )
@@ -290,6 +307,106 @@ enum A { One(One) }"#,
290
307
"enum A { $0One { foo: u32 } }" ,
291
308
r#"struct One{ pub foo: u32 }
292
309
310
+ enum A { One(One) }"# ,
311
+ ) ;
312
+ }
313
+
314
+ #[ test]
315
+ fn test_extract_struct_keep_comments_and_attrs_one_field_named ( ) {
316
+ check_assist (
317
+ extract_struct_from_enum_variant,
318
+ r#"
319
+ enum A {
320
+ $0One {
321
+ // leading comment
322
+ /// doc comment
323
+ #[an_attr]
324
+ foo: u32
325
+ // trailing comment
326
+ }
327
+ }"# ,
328
+ r#"
329
+ struct One{
330
+ // leading comment
331
+ /// doc comment
332
+ #[an_attr]
333
+ pub foo: u32
334
+ // trailing comment
335
+ }
336
+
337
+ enum A {
338
+ One(One)
339
+ }"# ,
340
+ ) ;
341
+ }
342
+
343
+ #[ test]
344
+ fn test_extract_struct_keep_comments_and_attrs_several_fields_named ( ) {
345
+ check_assist (
346
+ extract_struct_from_enum_variant,
347
+ r#"
348
+ enum A {
349
+ $0One {
350
+ // comment
351
+ /// doc
352
+ #[attr]
353
+ foo: u32,
354
+ // comment
355
+ #[attr]
356
+ /// doc
357
+ bar: u32
358
+ }
359
+ }"# ,
360
+ r#"
361
+ struct One{
362
+ // comment
363
+ /// doc
364
+ #[attr]
365
+ pub foo: u32,
366
+ // comment
367
+ #[attr]
368
+ /// doc
369
+ pub bar: u32
370
+ }
371
+
372
+ enum A {
373
+ One(One)
374
+ }"# ,
375
+ ) ;
376
+ }
377
+
378
+ #[ test]
379
+ fn test_extract_struct_keep_comments_and_attrs_several_fields_tuple ( ) {
380
+ check_assist (
381
+ extract_struct_from_enum_variant,
382
+ "enum A { $0One(/* comment */ #[attr] u32, /* another */ u32 /* tail */) }" ,
383
+ r#"
384
+ struct One(/* comment */ #[attr] pub u32, /* another */ pub u32 /* tail */);
385
+
386
+ enum A { One(One) }"# ,
387
+ ) ;
388
+ }
389
+
390
+ #[ test]
391
+ fn test_extract_struct_keep_existing_visibility_named ( ) {
392
+ check_assist (
393
+ extract_struct_from_enum_variant,
394
+ "enum A { $0One{ pub a: u32, pub(crate) b: u32, pub(super) c: u32, d: u32 } }" ,
395
+ r#"
396
+ struct One{ pub a: u32, pub(crate) b: u32, pub(super) c: u32, pub d: u32 }
397
+
398
+ enum A { One(One) }"# ,
399
+ ) ;
400
+ }
401
+
402
+ #[ test]
403
+ fn test_extract_struct_keep_existing_visibility_tuple ( ) {
404
+ check_assist (
405
+ extract_struct_from_enum_variant,
406
+ "enum A { $0One(pub u32, pub(crate) u32, pub(super) u32, u32) }" ,
407
+ r#"
408
+ struct One(pub u32, pub(crate) u32, pub(super) u32, pub u32);
409
+
293
410
enum A { One(One) }"# ,
294
411
) ;
295
412
}
0 commit comments