]> git.lizzy.rs Git - rust.git/blob - crates/ide_assists/src/handlers/replace_string_with_char.rs
Only replace quotes in replace_string_with_char assist
[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     let quote_offets = token.quote_offsets()?;
29
30     acc.add(
31         AssistId("replace_string_with_char", AssistKind::RefactorRewrite),
32         "Replace string with char",
33         target,
34         |edit| {
35             let (left, right) = quote_offets.quotes;
36             edit.replace(left, String::from('\''));
37             edit.replace(right, String::from('\''));
38         },
39     )
40 }
41
42 #[cfg(test)]
43 mod tests {
44     use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
45
46     use super::*;
47
48     #[test]
49     fn replace_string_with_char_target() {
50         check_assist_target(
51             replace_string_with_char,
52             r#"
53 fn f() {
54     let s = "$0c";
55 }
56 "#,
57             r#""c""#,
58         );
59     }
60
61     #[test]
62     fn replace_string_with_char_assist() {
63         check_assist(
64             replace_string_with_char,
65             r#"
66 fn f() {
67     let s = "$0c";
68 }
69 "#,
70             r##"
71 fn f() {
72     let s = 'c';
73 }
74 "##,
75         )
76     }
77
78     #[test]
79     fn replace_string_with_char_assist_with_emoji() {
80         check_assist(
81             replace_string_with_char,
82             r#"
83 fn f() {
84     let s = "$0😀";
85 }
86 "#,
87             r##"
88 fn f() {
89     let s = '😀';
90 }
91 "##,
92         )
93     }
94
95     #[test]
96     fn replace_string_with_char_assist_not_applicable() {
97         check_assist_not_applicable(
98             replace_string_with_char,
99             r#"
100 fn f() {
101     let s = "$0test";
102 }
103 "#,
104         )
105     }
106
107     #[test]
108     fn replace_string_with_char_works_inside_macros() {
109         check_assist(
110             replace_string_with_char,
111             r#"
112 fn f() {
113     format!($0"x", 92)
114 }
115 "#,
116             r##"
117 fn f() {
118     format!('x', 92)
119 }
120 "##,
121         )
122     }
123
124     #[test]
125     fn replace_string_with_char_works_func_args() {
126         check_assist(
127             replace_string_with_char,
128             r#"
129 fn f() {
130     find($0"x");
131 }
132 "#,
133             r##"
134 fn f() {
135     find('x');
136 }
137 "##,
138         )
139     }
140
141     #[test]
142     fn replace_string_with_char_newline() {
143         check_assist(
144             replace_string_with_char,
145             r#"
146 fn f() {
147     find($0"\n");
148 }
149 "#,
150             r##"
151 fn f() {
152     find('\n');
153 }
154 "##,
155         )
156     }
157
158     #[test]
159     fn replace_string_with_char_unicode_escape() {
160         check_assist(
161             replace_string_with_char,
162             r#"
163 fn f() {
164     find($0"\u{7FFF}");
165 }
166 "#,
167             r##"
168 fn f() {
169     find('\u{7FFF}');
170 }
171 "##,
172         )
173     }
174
175     #[test]
176     fn replace_raw_string_with_char() {
177         check_assist(
178             replace_string_with_char,
179             r##"
180 fn f() {
181     $0r#"X"#
182 }
183 "##,
184             r##"
185 fn f() {
186     'X'
187 }
188 "##,
189         )
190     }
191 }