aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers/add_from_impl_for_enum.rs')
-rw-r--r--crates/ra_assists/src/handlers/add_from_impl_for_enum.rs44
1 files changed, 20 insertions, 24 deletions
diff --git a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
index 49deb6701..6a675e812 100644
--- a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
+++ b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
@@ -1,12 +1,8 @@
1use ra_ide_db::RootDatabase; 1use ra_ide_db::RootDatabase;
2use ra_syntax::{ 2use ra_syntax::ast::{self, AstNode, NameOwner};
3 ast::{self, AstNode, NameOwner}, 3use test_utils::mark;
4 TextSize,
5};
6use stdx::format_to;
7 4
8use crate::{utils::FamousDefs, Assist, AssistCtx, AssistId}; 5use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
9use test_utils::tested_by;
10 6
11// Assist add_from_impl_for_enum 7// Assist add_from_impl_for_enum
12// 8//
@@ -25,7 +21,7 @@ use test_utils::tested_by;
25// } 21// }
26// } 22// }
27// ``` 23// ```
28pub(crate) fn add_from_impl_for_enum(ctx: AssistCtx) -> Option<Assist> { 24pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
29 let variant = ctx.find_node_at_offset::<ast::EnumVariant>()?; 25 let variant = ctx.find_node_at_offset::<ast::EnumVariant>()?;
30 let variant_name = variant.name()?; 26 let variant_name = variant.name()?;
31 let enum_name = variant.parent_enum().name()?; 27 let enum_name = variant.parent_enum().name()?;
@@ -38,23 +34,23 @@ pub(crate) fn add_from_impl_for_enum(ctx: AssistCtx) -> Option<Assist> {
38 } 34 }
39 let field_type = field_list.fields().next()?.type_ref()?; 35 let field_type = field_list.fields().next()?.type_ref()?;
40 let path = match field_type { 36 let path = match field_type {
41 ast::TypeRef::PathType(p) => p, 37 ast::TypeRef::PathType(it) => it,
42 _ => return None, 38 _ => return None,
43 }; 39 };
44 40
45 if existing_from_impl(ctx.sema, &variant).is_some() { 41 if existing_from_impl(&ctx.sema, &variant).is_some() {
46 tested_by!(test_add_from_impl_already_exists); 42 mark::hit!(test_add_from_impl_already_exists);
47 return None; 43 return None;
48 } 44 }
49 45
50 ctx.add_assist( 46 let target = variant.syntax().text_range();
47 acc.add(
51 AssistId("add_from_impl_for_enum"), 48 AssistId("add_from_impl_for_enum"),
52 "Add From impl for this enum variant", 49 "Add From impl for this enum variant",
50 target,
53 |edit| { 51 |edit| {
54 let start_offset = variant.parent_enum().syntax().text_range().end(); 52 let start_offset = variant.parent_enum().syntax().text_range().end();
55 let mut buf = String::new(); 53 let buf = format!(
56 format_to!(
57 buf,
58 r#" 54 r#"
59 55
60impl From<{0}> for {1} {{ 56impl From<{0}> for {1} {{
@@ -67,7 +63,6 @@ impl From<{0}> for {1} {{
67 variant_name 63 variant_name
68 ); 64 );
69 edit.insert(start_offset, buf); 65 edit.insert(start_offset, buf);
70 edit.set_cursor(start_offset + TextSize::of("\n\n"));
71 }, 66 },
72 ) 67 )
73} 68}
@@ -95,10 +90,11 @@ fn existing_from_impl(
95 90
96#[cfg(test)] 91#[cfg(test)]
97mod tests { 92mod tests {
98 use super::*; 93 use test_utils::mark;
94
95 use crate::tests::{check_assist, check_assist_not_applicable};
99 96
100 use crate::helpers::{check_assist, check_assist_not_applicable}; 97 use super::*;
101 use test_utils::covers;
102 98
103 #[test] 99 #[test]
104 fn test_add_from_impl_for_enum() { 100 fn test_add_from_impl_for_enum() {
@@ -107,7 +103,7 @@ mod tests {
107 "enum A { <|>One(u32) }", 103 "enum A { <|>One(u32) }",
108 r#"enum A { One(u32) } 104 r#"enum A { One(u32) }
109 105
110<|>impl From<u32> for A { 106impl From<u32> for A {
111 fn from(v: u32) -> Self { 107 fn from(v: u32) -> Self {
112 A::One(v) 108 A::One(v)
113 } 109 }
@@ -119,10 +115,10 @@ mod tests {
119 fn test_add_from_impl_for_enum_complicated_path() { 115 fn test_add_from_impl_for_enum_complicated_path() {
120 check_assist( 116 check_assist(
121 add_from_impl_for_enum, 117 add_from_impl_for_enum,
122 "enum A { <|>One(foo::bar::baz::Boo) }", 118 r#"enum A { <|>One(foo::bar::baz::Boo) }"#,
123 r#"enum A { One(foo::bar::baz::Boo) } 119 r#"enum A { One(foo::bar::baz::Boo) }
124 120
125<|>impl From<foo::bar::baz::Boo> for A { 121impl From<foo::bar::baz::Boo> for A {
126 fn from(v: foo::bar::baz::Boo) -> Self { 122 fn from(v: foo::bar::baz::Boo) -> Self {
127 A::One(v) 123 A::One(v)
128 } 124 }
@@ -153,7 +149,7 @@ mod tests {
153 149
154 #[test] 150 #[test]
155 fn test_add_from_impl_already_exists() { 151 fn test_add_from_impl_already_exists() {
156 covers!(test_add_from_impl_already_exists); 152 mark::check!(test_add_from_impl_already_exists);
157 check_not_applicable( 153 check_not_applicable(
158 r#" 154 r#"
159enum A { <|>One(u32), } 155enum A { <|>One(u32), }
@@ -184,7 +180,7 @@ pub trait From<T> {
184}"#, 180}"#,
185 r#"enum A { One(u32), Two(String), } 181 r#"enum A { One(u32), Two(String), }
186 182
187<|>impl From<u32> for A { 183impl From<u32> for A {
188 fn from(v: u32) -> Self { 184 fn from(v: u32) -> Self {
189 A::One(v) 185 A::One(v)
190 } 186 }