1 use stdx::to_lower_snake_case;
2 use syntax::ast::VisibilityOwner;
3 use syntax::ast::{self, AstNode, NameOwner};
6 utils::{add_method_to_adt, find_struct_impl},
7 AssistContext, AssistId, AssistKind, Assists,
10 // Assist: generate_enum_is_method
12 // Generate an `is_` method for an enum variant.
30 // /// Returns `true` if the version is [`Minor`].
32 // /// [`Minor`]: Version::Minor
33 // fn is_minor(&self) -> bool {
34 // matches!(self, Self::Minor)
38 pub(crate) fn generate_enum_is_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
39 let variant = ctx.find_node_at_offset::<ast::Variant>()?;
40 let variant_name = variant.name()?;
41 let parent_enum = ast::Adt::Enum(variant.parent_enum());
42 let pattern_suffix = match variant.kind() {
43 ast::StructKind::Record(_) => " { .. }",
44 ast::StructKind::Tuple(_) => "(..)",
45 ast::StructKind::Unit => "",
48 let enum_name = parent_enum.name()?;
49 let enum_lowercase_name = to_lower_snake_case(&enum_name.to_string()).replace('_', " ");
50 let fn_name = format!("is_{}", &to_lower_snake_case(&variant_name.text()));
52 // Return early if we've found an existing new fn
53 let impl_def = find_struct_impl(ctx, &parent_enum, &fn_name)?;
55 let target = variant.syntax().text_range();
57 AssistId("generate_enum_is_method", AssistKind::Generate),
58 "Generate an `is_` method for an enum variant",
61 let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v));
63 " /// Returns `true` if the {} is [`{variant}`].
65 /// [`{variant}`]: {}::{variant}
66 {}fn {}(&self) -> bool {{
67 matches!(self, Self::{variant}{})
74 variant = variant_name
77 add_method_to_adt(builder, &parent_enum, impl_def, &method);
84 use crate::tests::{check_assist, check_assist_not_applicable};
89 fn test_generate_enum_is_from_variant() {
91 generate_enum_is_method,
105 /// Returns `true` if the variant is [`Minor`].
107 /// [`Minor`]: Variant::Minor
108 fn is_minor(&self) -> bool {
109 matches!(self, Self::Minor)
116 fn test_generate_enum_is_already_implemented() {
117 check_assist_not_applicable(
118 generate_enum_is_method,
127 fn is_minor(&self) -> bool {
128 matches!(self, Self::Minor)
135 fn test_generate_enum_is_from_tuple_variant() {
137 generate_enum_is_method,
151 /// Returns `true` if the variant is [`Minor`].
153 /// [`Minor`]: Variant::Minor
154 fn is_minor(&self) -> bool {
155 matches!(self, Self::Minor(..))
162 fn test_generate_enum_is_from_record_variant() {
164 generate_enum_is_method,
168 Minor { foo: i32 }$0,
178 /// Returns `true` if the variant is [`Minor`].
180 /// [`Minor`]: Variant::Minor
181 fn is_minor(&self) -> bool {
182 matches!(self, Self::Minor { .. })
189 fn test_generate_enum_is_from_variant_with_one_variant() {
191 generate_enum_is_method,
192 r#"enum Variant { Undefi$0ned }"#,
194 enum Variant { Undefined }
197 /// Returns `true` if the variant is [`Undefined`].
199 /// [`Undefined`]: Variant::Undefined
200 fn is_undefined(&self) -> bool {
201 matches!(self, Self::Undefined)
208 fn test_generate_enum_is_from_variant_with_visibility_marker() {
210 generate_enum_is_method,
212 pub(crate) enum Variant {
217 r#"pub(crate) enum Variant {
224 /// Returns `true` if the variant is [`Minor`].
226 /// [`Minor`]: Variant::Minor
227 pub(crate) fn is_minor(&self) -> bool {
228 matches!(self, Self::Minor)
235 fn test_multiple_generate_enum_is_from_variant() {
237 generate_enum_is_method,
246 /// Returns `true` if the variant is [`Minor`].
248 /// [`Minor`]: Variant::Minor
249 fn is_minor(&self) -> bool {
250 matches!(self, Self::Minor)
260 /// Returns `true` if the variant is [`Minor`].
262 /// [`Minor`]: Variant::Minor
263 fn is_minor(&self) -> bool {
264 matches!(self, Self::Minor)
267 /// Returns `true` if the variant is [`Major`].
269 /// [`Major`]: Variant::Major
270 fn is_major(&self) -> bool {
271 matches!(self, Self::Major)
278 fn test_generate_enum_is_variant_names() {
280 generate_enum_is_method,
282 enum GeneratorState {
287 r#"enum GeneratorState {
293 impl GeneratorState {
294 /// Returns `true` if the generator state is [`Complete`].
296 /// [`Complete`]: GeneratorState::Complete
297 fn is_complete(&self) -> bool {
298 matches!(self, Self::Complete)