]> git.lizzy.rs Git - rust.git/blob - crates/ide_assists/src/handlers/replace_string_with_char.rs
Merge #7865
[rust.git] / crates / ide_assists / src / handlers / replace_string_with_char.rs
1 use syntax::{ast, AstToken, SyntaxKind::STRING};
2
3 use crate::{AssistContext, AssistId, AssistKind, Assists};
4
5 // Assist: replace_string_with_char
6 //
7 // Replace string with char.
8 //
9 // ```
10 // fn main() {
11 //     find("{$0");
12 // }
13 // ```
14 // ->
15 // ```
16 // fn main() {
17 //     find('{');
18 // }
19 // ```
20 pub(crate) fn replace_string_with_char(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
21     let token = ctx.find_token_syntax_at_offset(STRING).and_then(ast::String::cast)?;
22     let value = token.value()?;
23     let target = token.syntax().text_range();
24
25     if value.chars().take(2).count() != 1 {
26         return None;
27     }
28
29     acc.add(
30         AssistId("replace_string_with_char", AssistKind::RefactorRewrite),
31         "Replace string with char",
32         target,
33         |edit| {
34             let token_text = token.syntax().text();
35             let inner_text = &token_text[1..token_text.len() - 1];
36             edit.replace(token.syntax().text_range(), format!("'{}'", inner_text));
37         },
38     )
39 }
40
41 #[cfg(test)]
42 mod tests {
43     use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
44
45     use super::*;
46
47     #[test]
48     fn replace_string_with_char_target() {
49         check_assist_target(
50             replace_string_with_char,
51             r#"
52             fn f() {
53                 let s = "$0c";
54             }
55             "#,
56             r#""c""#,
57         );
58     }
59
60     #[test]
61     fn replace_string_with_char_assist() {
62         check_assist(
63             replace_string_with_char,
64             r#"
65     fn f() {
66         let s = "$0c";
67     }
68     "#,
69             r##"
70     fn f() {
71         let s = 'c';
72     }
73     "##,
74         )
75     }
76
77     #[test]
78     fn replace_string_with_char_assist_with_emoji() {
79         check_assist(
80             replace_string_with_char,
81             r#"
82     fn f() {
83         let s = "$0😀";
84     }
85     "#,
86             r##"
87     fn f() {
88         let s = '😀';
89     }
90     "##,
91         )
92     }
93
94     #[test]
95     fn replace_string_with_char_assist_not_applicable() {
96         check_assist_not_applicable(
97             replace_string_with_char,
98             r#"
99     fn f() {
100         let s = "$0test";
101     }
102     "#,
103         )
104     }
105
106     #[test]
107     fn replace_string_with_char_works_inside_macros() {
108         check_assist(
109             replace_string_with_char,
110             r#"
111                 fn f() {
112                     format!($0"x", 92)
113                 }
114                 "#,
115             r##"
116                 fn f() {
117                     format!('x', 92)
118                 }
119                 "##,
120         )
121     }
122
123     #[test]
124     fn replace_string_with_char_works_func_args() {
125         check_assist(
126             replace_string_with_char,
127             r#"
128                 fn f() {
129                     find($0"x");
130                 }
131                 "#,
132             r##"
133                 fn f() {
134                     find('x');
135                 }
136                 "##,
137         )
138     }
139
140     #[test]
141     fn replace_string_with_char_newline() {
142         check_assist(
143             replace_string_with_char,
144             r#"
145                 fn f() {
146                     find($0"\n");
147                 }
148                 "#,
149             r##"
150                 fn f() {
151                     find('\n');
152                 }
153                 "##,
154         )
155     }
156
157     #[test]
158     fn replace_string_with_char_unicode_escape() {
159         check_assist(
160             replace_string_with_char,
161             r#"
162                 fn f() {
163                     find($0"\u{7FFF}");
164                 }
165                 "#,
166             r##"
167                 fn f() {
168                     find('\u{7FFF}');
169                 }
170                 "##,
171         )
172     }
173 }