diff options
Diffstat (limited to 'crates/ra_assists/src/assists')
-rw-r--r-- | crates/ra_assists/src/assists/raw_string.rs | 49 |
1 files changed, 24 insertions, 25 deletions
diff --git a/crates/ra_assists/src/assists/raw_string.rs b/crates/ra_assists/src/assists/raw_string.rs index b182687a4..200aaa59a 100644 --- a/crates/ra_assists/src/assists/raw_string.rs +++ b/crates/ra_assists/src/assists/raw_string.rs | |||
@@ -12,40 +12,39 @@ pub(crate) fn make_raw_string(mut ctx: AssistCtx<impl HirDatabase>) -> Option<As | |||
12 | let token = literal.token(); | 12 | let token = literal.token(); |
13 | let text = token.text().as_str(); | 13 | let text = token.text().as_str(); |
14 | let usual_string_range = find_usual_string_range(text)?; | 14 | let usual_string_range = find_usual_string_range(text)?; |
15 | let start_of_inside = usual_string_range.start().to_usize() + 1; | ||
16 | let end_of_inside = usual_string_range.end().to_usize(); | ||
17 | let inside_str = &text[start_of_inside..end_of_inside]; | ||
18 | let mut unescaped = String::with_capacity(inside_str.len()); | ||
19 | let mut error = Ok(()); | ||
20 | rustc_lexer::unescape::unescape_str( | ||
21 | inside_str, | ||
22 | &mut |_, unescaped_char| match unescaped_char { | ||
23 | Ok(c) => unescaped.push(c), | ||
24 | Err(_) => error = Err(()), | ||
25 | }, | ||
26 | ); | ||
27 | if error.is_err() { | ||
28 | return None; | ||
29 | } | ||
15 | ctx.add_action(AssistId("make_raw_string"), "make raw string", |edit| { | 30 | ctx.add_action(AssistId("make_raw_string"), "make raw string", |edit| { |
16 | edit.target(literal.syntax().text_range()); | 31 | edit.target(literal.syntax().text_range()); |
17 | let start_of_inside = usual_string_range.start().to_usize() + 1; | 32 | let max_hash_streak = count_hashes(&unescaped); |
18 | let end_of_inside = usual_string_range.end().to_usize(); | 33 | let mut hashes = String::with_capacity(max_hash_streak + 1); |
19 | let inside_str = &text[start_of_inside..end_of_inside]; | 34 | for _ in 0..hashes.capacity() { |
20 | let mut unescaped = String::with_capacity(inside_str.len()); | 35 | hashes.push('#'); |
21 | let mut error = Ok(()); | ||
22 | rustc_lexer::unescape::unescape_str(inside_str, &mut |_, unescaped_char| { | ||
23 | match unescaped_char { | ||
24 | Ok(c) => unescaped.push(c), | ||
25 | Err(_) => error = Err(()), | ||
26 | } | ||
27 | }); | ||
28 | if error.is_err() { | ||
29 | eprintln!("Error unescaping string"); | ||
30 | } else { | ||
31 | let max_hash_streak = count_hashes(&unescaped); | ||
32 | let mut hashes = String::with_capacity(max_hash_streak + 1); | ||
33 | for _ in 0..hashes.capacity() { | ||
34 | hashes.push('#'); | ||
35 | } | ||
36 | edit.replace( | ||
37 | literal.syntax().text_range(), | ||
38 | format!("r{}\"{}\"{}", hashes, unescaped, hashes), | ||
39 | ); | ||
40 | } | 36 | } |
37 | edit.replace( | ||
38 | literal.syntax().text_range(), | ||
39 | format!("r{}\"{}\"{}", hashes, unescaped, hashes), | ||
40 | ); | ||
41 | }); | 41 | }); |
42 | ctx.build() | 42 | ctx.build() |
43 | } | 43 | } |
44 | 44 | ||
45 | fn count_hashes(s: &str) -> usize { | 45 | fn count_hashes(s: &str) -> usize { |
46 | let indexes: Vec<_> = s.match_indices("\"#").map(|(i, _)| i).collect(); | ||
47 | let mut max_hash_streak = 0usize; | 46 | let mut max_hash_streak = 0usize; |
48 | for idx in indexes { | 47 | for idx in s.match_indices("\"#").map(|(i, _)| i) { |
49 | let (_, sub) = s.split_at(idx + 1); | 48 | let (_, sub) = s.split_at(idx + 1); |
50 | let nb_hash = sub.chars().take_while(|c| *c == '#').count(); | 49 | let nb_hash = sub.chars().take_while(|c| *c == '#').count(); |
51 | if nb_hash > max_hash_streak { | 50 | if nb_hash > max_hash_streak { |