1
- use stdx:: { format_to , to_lower_snake_case} ;
1
+ use stdx:: to_lower_snake_case;
2
2
use syntax:: ast:: VisibilityOwner ;
3
3
use syntax:: ast:: { self , AstNode , NameOwner } ;
4
- use test_utils:: mark;
5
4
6
5
use crate :: {
7
- utils:: { find_impl_block_end , find_struct_impl, generate_impl_text } ,
6
+ utils:: { add_method_to_adt , find_struct_impl} ,
8
7
AssistContext , AssistId , AssistKind , Assists ,
9
8
} ;
10
9
11
- // Assist: generate_enum_match_method
10
+ // Assist: generate_enum_is_method
12
11
//
13
12
// Generate an `is_` method for an enum variant.
14
13
//
@@ -34,79 +33,52 @@ use crate::{
34
33
// }
35
34
// }
36
35
// ```
37
- pub ( crate ) fn generate_enum_match_method ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
36
+ pub ( crate ) fn generate_enum_is_method ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
38
37
let variant = ctx. find_node_at_offset :: < ast:: Variant > ( ) ?;
39
38
let variant_name = variant. name ( ) ?;
40
- let parent_enum = variant. parent_enum ( ) ;
41
- if !matches ! ( variant. kind( ) , ast:: StructKind :: Unit ) {
42
- mark:: hit!( test_gen_enum_match_on_non_unit_variant_not_implemented) ;
43
- return None ;
44
- }
39
+ let parent_enum = ast:: Adt :: Enum ( variant. parent_enum ( ) ) ;
40
+ let pattern_suffix = match variant. kind ( ) {
41
+ ast:: StructKind :: Record ( _) => " { .. }" ,
42
+ ast:: StructKind :: Tuple ( _) => "(..)" ,
43
+ ast:: StructKind :: Unit => "" ,
44
+ } ;
45
45
46
46
let enum_lowercase_name = to_lower_snake_case ( & parent_enum. name ( ) ?. to_string ( ) ) ;
47
- let fn_name = to_lower_snake_case ( & variant_name. to_string ( ) ) ;
47
+ let fn_name = format ! ( "is_{}" , & to_lower_snake_case ( variant_name. text ( ) ) ) ;
48
48
49
49
// Return early if we've found an existing new fn
50
- let impl_def = find_struct_impl (
51
- & ctx,
52
- & ast:: Adt :: Enum ( parent_enum. clone ( ) ) ,
53
- format ! ( "is_{}" , fn_name) . as_str ( ) ,
54
- ) ?;
50
+ let impl_def = find_struct_impl ( & ctx, & parent_enum, & fn_name) ?;
55
51
56
52
let target = variant. syntax ( ) . text_range ( ) ;
57
53
acc. add (
58
- AssistId ( "generate_enum_match_method " , AssistKind :: Generate ) ,
54
+ AssistId ( "generate_enum_is_method " , AssistKind :: Generate ) ,
59
55
"Generate an `is_` method for an enum variant" ,
60
56
target,
61
57
|builder| {
62
- let mut buf = String :: with_capacity ( 512 ) ;
63
-
64
- if impl_def. is_some ( ) {
65
- buf. push ( '\n' ) ;
66
- }
67
-
68
58
let vis = parent_enum. visibility ( ) . map_or ( String :: new ( ) , |v| format ! ( "{} " , v) ) ;
69
- format_to ! (
70
- buf,
59
+ let method = format ! (
71
60
" /// Returns `true` if the {} is [`{}`].
72
- {}fn is_ {}(&self) -> bool {{
73
- matches!(self, Self::{})
61
+ {}fn {}(&self) -> bool {{
62
+ matches!(self, Self::{}{} )
74
63
}}" ,
75
- enum_lowercase_name,
76
- variant_name,
77
- vis,
78
- fn_name,
79
- variant_name
64
+ enum_lowercase_name, variant_name, vis, fn_name, variant_name, pattern_suffix,
80
65
) ;
81
66
82
- let start_offset = impl_def
83
- . and_then ( |impl_def| find_impl_block_end ( impl_def, & mut buf) )
84
- . unwrap_or_else ( || {
85
- buf = generate_impl_text ( & ast:: Adt :: Enum ( parent_enum. clone ( ) ) , & buf) ;
86
- parent_enum. syntax ( ) . text_range ( ) . end ( )
87
- } ) ;
88
-
89
- builder. insert ( start_offset, buf) ;
67
+ add_method_to_adt ( builder, & parent_enum, impl_def, & method) ;
90
68
} ,
91
69
)
92
70
}
93
71
94
72
#[ cfg( test) ]
95
73
mod tests {
96
- use test_utils:: mark;
97
-
98
74
use crate :: tests:: { check_assist, check_assist_not_applicable} ;
99
75
100
76
use super :: * ;
101
77
102
- fn check_not_applicable ( ra_fixture : & str ) {
103
- check_assist_not_applicable ( generate_enum_match_method, ra_fixture)
104
- }
105
-
106
78
#[ test]
107
- fn test_generate_enum_match_from_variant ( ) {
79
+ fn test_generate_enum_is_from_variant ( ) {
108
80
check_assist (
109
- generate_enum_match_method ,
81
+ generate_enum_is_method ,
110
82
r#"
111
83
enum Variant {
112
84
Undefined,
@@ -129,8 +101,9 @@ impl Variant {
129
101
}
130
102
131
103
#[ test]
132
- fn test_generate_enum_match_already_implemented ( ) {
133
- check_not_applicable (
104
+ fn test_generate_enum_is_already_implemented ( ) {
105
+ check_assist_not_applicable (
106
+ generate_enum_is_method,
134
107
r#"
135
108
enum Variant {
136
109
Undefined,
@@ -147,22 +120,59 @@ impl Variant {
147
120
}
148
121
149
122
#[ test]
150
- fn test_add_from_impl_no_element ( ) {
151
- mark :: check! ( test_gen_enum_match_on_non_unit_variant_not_implemented ) ;
152
- check_not_applicable (
123
+ fn test_generate_enum_is_from_tuple_variant ( ) {
124
+ check_assist (
125
+ generate_enum_is_method ,
153
126
r#"
154
127
enum Variant {
155
128
Undefined,
156
129
Minor(u32)$0,
157
130
Major,
131
+ }"# ,
132
+ r#"enum Variant {
133
+ Undefined,
134
+ Minor(u32),
135
+ Major,
136
+ }
137
+
138
+ impl Variant {
139
+ /// Returns `true` if the variant is [`Minor`].
140
+ fn is_minor(&self) -> bool {
141
+ matches!(self, Self::Minor(..))
142
+ }
143
+ }"# ,
144
+ ) ;
145
+ }
146
+
147
+ #[ test]
148
+ fn test_generate_enum_is_from_record_variant ( ) {
149
+ check_assist (
150
+ generate_enum_is_method,
151
+ r#"
152
+ enum Variant {
153
+ Undefined,
154
+ Minor { foo: i32 }$0,
155
+ Major,
156
+ }"# ,
157
+ r#"enum Variant {
158
+ Undefined,
159
+ Minor { foo: i32 },
160
+ Major,
161
+ }
162
+
163
+ impl Variant {
164
+ /// Returns `true` if the variant is [`Minor`].
165
+ fn is_minor(&self) -> bool {
166
+ matches!(self, Self::Minor { .. })
167
+ }
158
168
}"# ,
159
169
) ;
160
170
}
161
171
162
172
#[ test]
163
- fn test_generate_enum_match_from_variant_with_one_variant ( ) {
173
+ fn test_generate_enum_is_from_variant_with_one_variant ( ) {
164
174
check_assist (
165
- generate_enum_match_method ,
175
+ generate_enum_is_method ,
166
176
r#"enum Variant { Undefi$0ned }"# ,
167
177
r#"
168
178
enum Variant { Undefined }
@@ -177,9 +187,9 @@ impl Variant {
177
187
}
178
188
179
189
#[ test]
180
- fn test_generate_enum_match_from_variant_with_visibility_marker ( ) {
190
+ fn test_generate_enum_is_from_variant_with_visibility_marker ( ) {
181
191
check_assist (
182
- generate_enum_match_method ,
192
+ generate_enum_is_method ,
183
193
r#"
184
194
pub(crate) enum Variant {
185
195
Undefined,
@@ -202,9 +212,9 @@ impl Variant {
202
212
}
203
213
204
214
#[ test]
205
- fn test_multiple_generate_enum_match_from_variant ( ) {
215
+ fn test_multiple_generate_enum_is_from_variant ( ) {
206
216
check_assist (
207
- generate_enum_match_method ,
217
+ generate_enum_is_method ,
208
218
r#"
209
219
enum Variant {
210
220
Undefined,
0 commit comments