aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src/handlers/generate_enum_is_method.rs
diff options
context:
space:
mode:
authorDomantas Jadenkus <[email protected]>2021-02-15 21:28:57 +0000
committerDomantas Jadenkus <[email protected]>2021-02-27 10:21:56 +0000
commitd4b6cbe5b6b9c90b577da7788669b6b6995ae524 (patch)
tree892bfb2f34462a8ba60103b95c9933bfc205932e /crates/ide_assists/src/handlers/generate_enum_is_method.rs
parentf098a2b31bffafdbd513f32e8c45d62e709173ea (diff)
rename generate_enum_match_method file to match assist name
Diffstat (limited to 'crates/ide_assists/src/handlers/generate_enum_is_method.rs')
-rw-r--r--crates/ide_assists/src/handlers/generate_enum_is_method.rs250
1 files changed, 250 insertions, 0 deletions
diff --git a/crates/ide_assists/src/handlers/generate_enum_is_method.rs b/crates/ide_assists/src/handlers/generate_enum_is_method.rs
new file mode 100644
index 000000000..7e181a480
--- /dev/null
+++ b/crates/ide_assists/src/handlers/generate_enum_is_method.rs
@@ -0,0 +1,250 @@
1use stdx::to_lower_snake_case;
2use syntax::ast::VisibilityOwner;
3use syntax::ast::{self, AstNode, NameOwner};
4
5use crate::{
6 utils::{add_method_to_adt, find_struct_impl},
7 AssistContext, AssistId, AssistKind, Assists,
8};
9
10// Assist: generate_enum_is_method
11//
12// Generate an `is_` method for an enum variant.
13//
14// ```
15// enum Version {
16// Undefined,
17// Minor$0,
18// Major,
19// }
20// ```
21// ->
22// ```
23// enum Version {
24// Undefined,
25// Minor,
26// Major,
27// }
28//
29// impl Version {
30// /// Returns `true` if the version is [`Minor`].
31// fn is_minor(&self) -> bool {
32// matches!(self, Self::Minor)
33// }
34// }
35// ```
36pub(crate) fn generate_enum_is_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
37 let variant = ctx.find_node_at_offset::<ast::Variant>()?;
38 let variant_name = variant.name()?;
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
46 let enum_lowercase_name = to_lower_snake_case(&parent_enum.name()?.to_string());
47 let fn_name = format!("is_{}", &to_lower_snake_case(variant_name.text()));
48
49 // Return early if we've found an existing new fn
50 let impl_def = find_struct_impl(&ctx, &parent_enum, &fn_name)?;
51
52 let target = variant.syntax().text_range();
53 acc.add(
54 AssistId("generate_enum_is_method", AssistKind::Generate),
55 "Generate an `is_` method for an enum variant",
56 target,
57 |builder| {
58 let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v));
59 let method = format!(
60 " /// Returns `true` if the {} is [`{}`].
61 {}fn {}(&self) -> bool {{
62 matches!(self, Self::{}{})
63 }}",
64 enum_lowercase_name, variant_name, vis, fn_name, variant_name, pattern_suffix,
65 );
66
67 add_method_to_adt(builder, &parent_enum, impl_def, &method);
68 },
69 )
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::tests::{check_assist, check_assist_not_applicable};
75
76 use super::*;
77
78 #[test]
79 fn test_generate_enum_is_from_variant() {
80 check_assist(
81 generate_enum_is_method,
82 r#"
83enum Variant {
84 Undefined,
85 Minor$0,
86 Major,
87}"#,
88 r#"enum Variant {
89 Undefined,
90 Minor,
91 Major,
92}
93
94impl Variant {
95 /// Returns `true` if the variant is [`Minor`].
96 fn is_minor(&self) -> bool {
97 matches!(self, Self::Minor)
98 }
99}"#,
100 );
101 }
102
103 #[test]
104 fn test_generate_enum_is_already_implemented() {
105 check_assist_not_applicable(
106 generate_enum_is_method,
107 r#"
108enum Variant {
109 Undefined,
110 Minor$0,
111 Major,
112}
113
114impl Variant {
115 fn is_minor(&self) -> bool {
116 matches!(self, Self::Minor)
117 }
118}"#,
119 );
120 }
121
122 #[test]
123 fn test_generate_enum_is_from_tuple_variant() {
124 check_assist(
125 generate_enum_is_method,
126 r#"
127enum Variant {
128 Undefined,
129 Minor(u32)$0,
130 Major,
131}"#,
132 r#"enum Variant {
133 Undefined,
134 Minor(u32),
135 Major,
136}
137
138impl 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#"
152enum 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
163impl Variant {
164 /// Returns `true` if the variant is [`Minor`].
165 fn is_minor(&self) -> bool {
166 matches!(self, Self::Minor { .. })
167 }
168}"#,
169 );
170 }
171
172 #[test]
173 fn test_generate_enum_is_from_variant_with_one_variant() {
174 check_assist(
175 generate_enum_is_method,
176 r#"enum Variant { Undefi$0ned }"#,
177 r#"
178enum Variant { Undefined }
179
180impl Variant {
181 /// Returns `true` if the variant is [`Undefined`].
182 fn is_undefined(&self) -> bool {
183 matches!(self, Self::Undefined)
184 }
185}"#,
186 );
187 }
188
189 #[test]
190 fn test_generate_enum_is_from_variant_with_visibility_marker() {
191 check_assist(
192 generate_enum_is_method,
193 r#"
194pub(crate) enum Variant {
195 Undefined,
196 Minor$0,
197 Major,
198}"#,
199 r#"pub(crate) enum Variant {
200 Undefined,
201 Minor,
202 Major,
203}
204
205impl Variant {
206 /// Returns `true` if the variant is [`Minor`].
207 pub(crate) fn is_minor(&self) -> bool {
208 matches!(self, Self::Minor)
209 }
210}"#,
211 );
212 }
213
214 #[test]
215 fn test_multiple_generate_enum_is_from_variant() {
216 check_assist(
217 generate_enum_is_method,
218 r#"
219enum Variant {
220 Undefined,
221 Minor,
222 Major$0,
223}
224
225impl Variant {
226 /// Returns `true` if the variant is [`Minor`].
227 fn is_minor(&self) -> bool {
228 matches!(self, Self::Minor)
229 }
230}"#,
231 r#"enum Variant {
232 Undefined,
233 Minor,
234 Major,
235}
236
237impl Variant {
238 /// Returns `true` if the variant is [`Minor`].
239 fn is_minor(&self) -> bool {
240 matches!(self, Self::Minor)
241 }
242
243 /// Returns `true` if the variant is [`Major`].
244 fn is_major(&self) -> bool {
245 matches!(self, Self::Major)
246 }
247}"#,
248 );
249 }
250}