1
1
use std:: cmp:: Ordering ;
2
2
3
- use hir:: known:: Option ;
4
3
use itertools:: Itertools ;
5
4
6
5
use syntax:: {
7
6
ast:: { self , NameOwner } ,
8
- ted, AstNode ,
7
+ ted, AstNode , TextRange ,
9
8
} ;
10
9
11
10
use crate :: { utils:: get_methods, AssistContext , AssistId , AssistKind , Assists } ;
@@ -18,12 +17,45 @@ pub(crate) fn sort_items(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
18
17
} else if let Some ( impl_ast) = ctx. find_node_at_offset :: < ast:: Impl > ( ) {
19
18
add_sort_methods_assist ( acc, impl_ast. assoc_item_list ( ) ?)
20
19
} else if let Some ( struct_ast) = ctx. find_node_at_offset :: < ast:: Struct > ( ) {
21
- add_sort_fields_assist ( acc, struct_ast. field_list ( ) ?)
20
+ match struct_ast. field_list ( ) {
21
+ Some ( ast:: FieldList :: RecordFieldList ( it) ) => add_sort_fields_assist ( acc, it) ,
22
+ _ => None ,
23
+ }
24
+ } else if let Some ( union_ast) = ctx. find_node_at_offset :: < ast:: Union > ( ) {
25
+ add_sort_fields_assist ( acc, union_ast. record_field_list ( ) ?)
22
26
} else {
23
27
None
24
28
}
25
29
}
26
30
31
+ trait AddRewrite {
32
+ fn add_rewrite < T : AstNode > (
33
+ & mut self ,
34
+ label : & str ,
35
+ old : Vec < T > ,
36
+ new : Vec < T > ,
37
+ target : TextRange ,
38
+ ) -> Option < ( ) > ;
39
+ }
40
+
41
+ impl AddRewrite for Assists {
42
+ fn add_rewrite < T : AstNode > (
43
+ & mut self ,
44
+ label : & str ,
45
+ old : Vec < T > ,
46
+ new : Vec < T > ,
47
+ target : TextRange ,
48
+ ) -> Option < ( ) > {
49
+ self . add ( AssistId ( "sort_items" , AssistKind :: RefactorRewrite ) , label, target, |builder| {
50
+ let mutable: Vec < _ > = old. into_iter ( ) . map ( |it| builder. make_mut ( it) ) . collect ( ) ;
51
+ mutable
52
+ . into_iter ( )
53
+ . zip ( new)
54
+ . for_each ( |( old, new) | ted:: replace ( old. syntax ( ) , new. clone_for_update ( ) . syntax ( ) ) ) ;
55
+ } )
56
+ }
57
+ }
58
+
27
59
fn add_sort_methods_assist ( acc : & mut Assists , item_list : ast:: AssocItemList ) -> Option < ( ) > {
28
60
let methods = get_methods ( & item_list) ;
29
61
let sorted = sort_by_name ( & methods) ;
@@ -33,47 +65,26 @@ fn add_sort_methods_assist(acc: &mut Assists, item_list: ast::AssocItemList) ->
33
65
return None ;
34
66
}
35
67
36
- acc. add (
37
- AssistId ( "sort_items" , AssistKind :: RefactorRewrite ) ,
38
- "Sort methods alphabetically" ,
39
- item_list. syntax ( ) . text_range ( ) ,
40
- |builder| {
41
- let methods = methods. into_iter ( ) . map ( |fn_| builder. make_mut ( fn_) ) . collect :: < Vec < _ > > ( ) ;
42
- methods
43
- . into_iter ( )
44
- . zip ( sorted)
45
- . for_each ( |( old, new) | ted:: replace ( old. syntax ( ) , new. clone_for_update ( ) . syntax ( ) ) ) ;
46
- } ,
47
- )
68
+ acc. add_rewrite ( "Sort methods alphabetically" , methods, sorted, item_list. syntax ( ) . text_range ( ) )
48
69
}
49
70
50
- fn add_sort_fields_assist ( acc : & mut Assists , field_list : ast:: FieldList ) -> Option < ( ) > {
51
- fn record_fields ( field_list : & ast:: FieldList ) -> Option < Vec < ast:: RecordField > > {
52
- match field_list {
53
- ast:: FieldList :: RecordFieldList ( it) => Some ( it. fields ( ) . collect ( ) ) ,
54
- ast:: FieldList :: TupleFieldList ( _) => None ,
55
- }
56
- }
57
-
58
- let fields = record_fields ( & field_list) ?;
71
+ fn add_sort_fields_assist (
72
+ acc : & mut Assists ,
73
+ record_field_list : ast:: RecordFieldList ,
74
+ ) -> Option < ( ) > {
75
+ let fields: Vec < _ > = record_field_list. fields ( ) . collect ( ) ;
59
76
let sorted = sort_by_name ( & fields) ;
60
77
61
78
if fields == sorted {
62
79
cov_mark:: hit!( not_applicable_if_sorted) ;
63
80
return None ;
64
81
}
65
82
66
- acc. add (
67
- AssistId ( "sort_items" , AssistKind :: RefactorRewrite ) ,
68
- "Sort methods alphabetically" ,
69
- field_list. syntax ( ) . text_range ( ) ,
70
- |builder| {
71
- let methods = fields. into_iter ( ) . map ( |fn_| builder. make_mut ( fn_) ) . collect :: < Vec < _ > > ( ) ;
72
- methods
73
- . into_iter ( )
74
- . zip ( sorted)
75
- . for_each ( |( old, new) | ted:: replace ( old. syntax ( ) , new. clone_for_update ( ) . syntax ( ) ) ) ;
76
- } ,
83
+ acc. add_rewrite (
84
+ "Sort fields alphabetically" ,
85
+ fields,
86
+ sorted,
87
+ record_field_list. syntax ( ) . text_range ( ) ,
77
88
)
78
89
}
79
90
@@ -147,6 +158,22 @@ $0struct Bar {
147
158
)
148
159
}
149
160
161
+ #[ test]
162
+ fn not_applicable_if_union_sorted ( ) {
163
+ cov_mark:: check!( not_applicable_if_sorted) ;
164
+
165
+ check_assist_not_applicable (
166
+ sort_items,
167
+ r#"
168
+ $0union Bar {
169
+ a: u32,
170
+ b: u8,
171
+ c: u64,
172
+ }
173
+ "# ,
174
+ )
175
+ }
176
+
150
177
#[ test]
151
178
fn sort_trait ( ) {
152
179
check_assist (
@@ -255,6 +282,27 @@ struct Bar {
255
282
a: usize,
256
283
aaa: u8,
257
284
b: u8,
285
+ }
286
+ "# ,
287
+ )
288
+ }
289
+
290
+ #[ test]
291
+ fn sort_union ( ) {
292
+ check_assist (
293
+ sort_items,
294
+ r#"
295
+ $0union Bar {
296
+ b: u8,
297
+ a: u32,
298
+ c: u64,
299
+ }
300
+ "# ,
301
+ r#"
302
+ union Bar {
303
+ a: u32,
304
+ b: u8,
305
+ c: u64,
258
306
}
259
307
"# ,
260
308
)
0 commit comments