aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/assists/src/handlers/generate_from_impl_for_enum.rs60
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
191impl 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]