diff options
-rw-r--r-- | crates/assists/src/handlers/generate_from_impl_for_enum.rs | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/crates/assists/src/handlers/generate_from_impl_for_enum.rs b/crates/assists/src/handlers/generate_from_impl_for_enum.rs index 95dc9c34a..c28eeff51 100644 --- a/crates/assists/src/handlers/generate_from_impl_for_enum.rs +++ b/crates/assists/src/handlers/generate_from_impl_for_enum.rs | |||
@@ -30,14 +30,22 @@ pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext | |||
30 | let variant_name = variant.name()?; | 30 | let variant_name = variant.name()?; |
31 | let enum_name = variant.parent_enum().name()?; | 31 | let enum_name = variant.parent_enum().name()?; |
32 | let enum_type_params = variant.parent_enum().generic_param_list(); | 32 | let enum_type_params = variant.parent_enum().generic_param_list(); |
33 | let field_list = match variant.kind() { | 33 | let (field_name, field_type) = match variant.kind() { |
34 | ast::StructKind::Tuple(field_list) => field_list, | 34 | ast::StructKind::Tuple(field_list) => { |
35 | _ => return None, | 35 | if field_list.fields().count() != 1 { |
36 | return None; | ||
37 | } | ||
38 | (None, field_list.fields().next()?.ty()?) | ||
39 | } | ||
40 | ast::StructKind::Record(field_list) => { | ||
41 | if field_list.fields().count() != 1 { | ||
42 | return None; | ||
43 | } | ||
44 | let field = field_list.fields().next()?; | ||
45 | (Some(field.name()?), field.ty()?) | ||
46 | } | ||
47 | ast::StructKind::Unit => return None, | ||
36 | }; | 48 | }; |
37 | if field_list.fields().count() != 1 { | ||
38 | return None; | ||
39 | } | ||
40 | let field_type = field_list.fields().next()?.ty()?; | ||
41 | 49 | ||
42 | if existing_from_impl(&ctx.sema, &variant).is_some() { | 50 | if existing_from_impl(&ctx.sema, &variant).is_some() { |
43 | mark::hit!(test_add_from_impl_already_exists); | 51 | mark::hit!(test_add_from_impl_already_exists); |
@@ -69,16 +77,30 @@ pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext | |||
69 | let generic_params = lifetime_params.chain(type_params).format(", "); | 77 | let generic_params = lifetime_params.chain(type_params).format(", "); |
70 | format_to!(buf, "<{}>", generic_params) | 78 | format_to!(buf, "<{}>", generic_params) |
71 | } | 79 | } |
72 | format_to!( | 80 | if let Some(name) = field_name { |
73 | buf, | 81 | format_to!( |
74 | r#" {{ | 82 | buf, |
83 | r#" {{ | ||
84 | fn from({0}: {1}) -> Self {{ | ||
85 | Self::{2} {{ {0} }} | ||
86 | }} | ||
87 | }}"#, | ||
88 | name.text(), | ||
89 | field_type.syntax(), | ||
90 | variant_name, | ||
91 | ); | ||
92 | } else { | ||
93 | format_to!( | ||
94 | buf, | ||
95 | r#" {{ | ||
75 | fn from(v: {}) -> Self {{ | 96 | fn from(v: {}) -> Self {{ |
76 | Self::{}(v) | 97 | Self::{}(v) |
77 | }} | 98 | }} |
78 | }}"#, | 99 | }}"#, |
79 | field_type.syntax(), | 100 | field_type.syntax(), |
80 | variant_name, | 101 | variant_name, |
81 | ); | 102 | ); |
103 | } | ||
82 | edit.insert(start_offset, buf); | 104 | edit.insert(start_offset, buf); |
83 | }, | 105 | }, |
84 | ) | 106 | ) |
@@ -161,7 +183,17 @@ impl From<foo::bar::baz::Boo> for A { | |||
161 | 183 | ||
162 | #[test] | 184 | #[test] |
163 | fn test_add_from_impl_struct_variant() { | 185 | fn test_add_from_impl_struct_variant() { |
164 | check_not_applicable("enum A { $0One { x: u32 } }"); | 186 | check_assist( |
187 | generate_from_impl_for_enum, | ||
188 | "enum A { $0One { x: u32 } }", | ||
189 | r#"enum A { One { x: u32 } } | ||
190 | |||
191 | impl From<u32> for A { | ||
192 | fn from(x: u32) -> Self { | ||
193 | Self::One { x } | ||
194 | } | ||
195 | }"#, | ||
196 | ); | ||
165 | } | 197 | } |
166 | 198 | ||
167 | #[test] | 199 | #[test] |