aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDomantas Jadenkus <[email protected]>2021-02-13 12:46:28 +0000
committerDomantas Jadenkus <[email protected]>2021-02-13 12:46:28 +0000
commit3a4d273ac2506fe5ab2ff2861e5ae702ab44eafe (patch)
treef8c0544a335fcd6a2e6d44c4a8e765d91889f18f
parente63116c74f79a7909998b27615a308268f9093d6 (diff)
handle generic enums
-rw-r--r--crates/assists/src/handlers/generate_from_impl_for_enum.rs66
1 files changed, 58 insertions, 8 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 ac9806368..8e68ebc7a 100644
--- a/crates/assists/src/handlers/generate_from_impl_for_enum.rs
+++ b/crates/assists/src/handlers/generate_from_impl_for_enum.rs
@@ -1,6 +1,9 @@
1use ast::GenericParamsOwner;
1use ide_db::helpers::FamousDefs; 2use ide_db::helpers::FamousDefs;
2use ide_db::RootDatabase; 3use ide_db::RootDatabase;
3use syntax::ast::{self, AstNode, NameOwner}; 4use itertools::Itertools;
5use stdx::format_to;
6use syntax::{SmolStr, ast::{self, AstNode, NameOwner}};
4use test_utils::mark; 7use test_utils::mark;
5 8
6use crate::{AssistContext, AssistId, AssistKind, Assists}; 9use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -26,6 +29,7 @@ pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext
26 let variant = ctx.find_node_at_offset::<ast::Variant>()?; 29 let variant = ctx.find_node_at_offset::<ast::Variant>()?;
27 let variant_name = variant.name()?; 30 let variant_name = variant.name()?;
28 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();
29 let field_list = match variant.kind() { 33 let field_list = match variant.kind() {
30 ast::StructKind::Tuple(field_list) => field_list, 34 ast::StructKind::Tuple(field_list) => field_list,
31 _ => return None, 35 _ => return None,
@@ -47,17 +51,33 @@ pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext
47 target, 51 target,
48 |edit| { 52 |edit| {
49 let start_offset = variant.parent_enum().syntax().text_range().end(); 53 let start_offset = variant.parent_enum().syntax().text_range().end();
50 let buf = format!( 54 let mut buf = String::from("\n\nimpl");
51 r#" 55 if let Some(type_params) = &enum_type_params {
56 format_to!(buf, "{}", type_params.syntax());
57 }
58 format_to!(buf, " From<{}> for {}", field_type.syntax(), enum_name);
59 if let Some(type_params) = enum_type_params {
60 let lifetime_params = type_params
61 .lifetime_params()
62 .filter_map(|it| it.lifetime())
63 .map(|it| SmolStr::from(it.text()));
64 let type_params = type_params
65 .type_params()
66 .filter_map(|it| it.name())
67 .map(|it| SmolStr::from(it.text()));
52 68
53impl From<{0}> for {1} {{ 69 let generic_params = lifetime_params.chain(type_params).format(", ");
54 fn from(v: {0}) -> Self {{ 70 format_to!(buf, "<{}>", generic_params)
55 Self::{2}(v) 71 }
72 format_to!(
73 buf,
74 r#" {{
75 fn from(v: {}) -> Self {{
76 Self::{}(v)
56 }} 77 }}
57}}"#, 78}}"#,
58 field_type.syntax(), 79 field_type.syntax(),
59 enum_name, 80 variant_name,
60 variant_name
61 ); 81 );
62 edit.insert(start_offset, buf); 82 edit.insert(start_offset, buf);
63 }, 83 },
@@ -209,4 +229,34 @@ impl From<&'static str> for A {
209}"#, 229}"#,
210 ); 230 );
211 } 231 }
232
233 #[test]
234 fn test_add_from_impl_generic_enum() {
235 check_assist(
236 generate_from_impl_for_enum,
237 "enum Generic<T, U: Clone> { $0One(T), Two(U) }",
238 r#"enum Generic<T, U: Clone> { One(T), Two(U) }
239
240impl<T, U: Clone> From<T> for Generic<T, U> {
241 fn from(v: T) -> Self {
242 Self::One(v)
243 }
244}"#,
245 );
246 }
247
248 #[test]
249 fn test_add_from_impl_with_lifetime() {
250 check_assist(
251 generate_from_impl_for_enum,
252 "enum Generic<'a> { $0One(&'a i32) }",
253 r#"enum Generic<'a> { One(&'a i32) }
254
255impl<'a> From<&'a i32> for Generic<'a> {
256 fn from(v: &'a i32) -> Self {
257 Self::One(v)
258 }
259}"#,
260 );
261 }
212} 262}