1- use syntax:: { ast, ast:: IsString , AstToken , SyntaxKind :: STRING } ;
1+ use syntax:: {
2+ ast,
3+ ast:: IsString ,
4+ AstToken ,
5+ SyntaxKind :: { CHAR , STRING } ,
6+ TextRange , TextSize ,
7+ } ;
28
39use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
410
511// Assist: replace_string_with_char
612//
7- // Replace string with char.
13+ // Replace string literal with char literal .
814//
915// ```
1016// fn main() {
@@ -33,31 +39,56 @@ pub(crate) fn replace_string_with_char(acc: &mut Assists, ctx: &AssistContext) -
3339 target,
3440 |edit| {
3541 let ( left, right) = quote_offets. quotes ;
36- edit. replace ( left, String :: from ( '\'' ) ) ;
37- edit. replace ( right, String :: from ( '\'' ) ) ;
42+ edit. replace ( left, '\'' ) ;
43+ edit. replace ( right, '\'' ) ;
44+ if value == "'" {
45+ edit. insert ( left. end ( ) , '\\' ) ;
46+ }
47+ } ,
48+ )
49+ }
50+
51+ // Assist: replace_char_with_string
52+ //
53+ // Replace a char literal with a string literal.
54+ //
55+ // ```
56+ // fn main() {
57+ // find('{$0');
58+ // }
59+ // ```
60+ // ->
61+ // ```
62+ // fn main() {
63+ // find("{");
64+ // }
65+ // ```
66+ pub ( crate ) fn replace_char_with_string ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
67+ let token = ctx. find_token_syntax_at_offset ( CHAR ) ?;
68+ let target = token. text_range ( ) ;
69+
70+ acc. add (
71+ AssistId ( "replace_char_with_string" , AssistKind :: RefactorRewrite ) ,
72+ "Replace char with string" ,
73+ target,
74+ |edit| {
75+ if token. text ( ) == "'\" '" {
76+ edit. replace ( token. text_range ( ) , r#""\"""# ) ;
77+ } else {
78+ let len = TextSize :: of ( '\'' ) ;
79+ edit. replace ( TextRange :: at ( target. start ( ) , len) , '"' ) ;
80+ edit. replace ( TextRange :: at ( target. end ( ) - len, len) , '"' ) ;
81+ }
3882 } ,
3983 )
4084}
4185
4286#[ cfg( test) ]
4387mod tests {
44- use crate :: tests:: { check_assist, check_assist_not_applicable, check_assist_target } ;
88+ use crate :: tests:: { check_assist, check_assist_not_applicable} ;
4589
4690 use super :: * ;
4791
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-
6192 #[ test]
6293 fn replace_string_with_char_assist ( ) {
6394 check_assist (
@@ -76,7 +107,7 @@ fn f() {
76107 }
77108
78109 #[ test]
79- fn replace_string_with_char_assist_with_emoji ( ) {
110+ fn replace_string_with_char_assist_with_multi_byte_char ( ) {
80111 check_assist (
81112 replace_string_with_char,
82113 r#"
@@ -93,7 +124,7 @@ fn f() {
93124 }
94125
95126 #[ test]
96- fn replace_string_with_char_assist_not_applicable ( ) {
127+ fn replace_string_with_char_multiple_chars ( ) {
97128 check_assist_not_applicable (
98129 replace_string_with_char,
99130 r#"
@@ -121,23 +152,6 @@ fn f() {
121152 )
122153 }
123154
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-
141155 #[ test]
142156 fn replace_string_with_char_newline ( ) {
143157 check_assist (
@@ -188,4 +202,106 @@ fn f() {
188202"## ,
189203 )
190204 }
205+
206+ #[ test]
207+ fn replace_char_with_string_assist ( ) {
208+ check_assist (
209+ replace_char_with_string,
210+ r"
211+ fn f() {
212+ let s = '$0c';
213+ }
214+ " ,
215+ r#"
216+ fn f() {
217+ let s = "c";
218+ }
219+ "# ,
220+ )
221+ }
222+
223+ #[ test]
224+ fn replace_char_with_string_assist_with_multi_byte_char ( ) {
225+ check_assist (
226+ replace_char_with_string,
227+ r"
228+ fn f() {
229+ let s = '$0😀';
230+ }
231+ " ,
232+ r#"
233+ fn f() {
234+ let s = "😀";
235+ }
236+ "# ,
237+ )
238+ }
239+
240+ #[ test]
241+ fn replace_char_with_string_newline ( ) {
242+ check_assist (
243+ replace_char_with_string,
244+ r"
245+ fn f() {
246+ find($0'\n');
247+ }
248+ " ,
249+ r#"
250+ fn f() {
251+ find("\n");
252+ }
253+ "# ,
254+ )
255+ }
256+
257+ #[ test]
258+ fn replace_char_with_string_unicode_escape ( ) {
259+ check_assist (
260+ replace_char_with_string,
261+ r"
262+ fn f() {
263+ find($0'\u{7FFF}');
264+ }
265+ " ,
266+ r#"
267+ fn f() {
268+ find("\u{7FFF}");
269+ }
270+ "# ,
271+ )
272+ }
273+
274+ #[ test]
275+ fn replace_char_with_string_quote ( ) {
276+ check_assist (
277+ replace_char_with_string,
278+ r#"
279+ fn f() {
280+ find($0'"');
281+ }
282+ "# ,
283+ r#"
284+ fn f() {
285+ find("\"");
286+ }
287+ "# ,
288+ )
289+ }
290+
291+ #[ test]
292+ fn replace_string_with_char_quote ( ) {
293+ check_assist (
294+ replace_string_with_char,
295+ r#"
296+ fn f() {
297+ find($0"'");
298+ }
299+ "# ,
300+ r#"
301+ fn f() {
302+ find('\'');
303+ }
304+ "# ,
305+ )
306+ }
191307}
0 commit comments