|
3 | 3 | use std::cmp::Ordering; |
4 | 4 | use std::ops::Range; |
5 | 5 |
|
| 6 | +use string_capacity::StringBuilder; |
| 7 | + |
6 | 8 | #[derive(Clone, Debug)] |
7 | 9 | pub struct TextChange { |
8 | 10 | /// Range start to end byte index. |
@@ -30,34 +32,32 @@ pub fn apply_text_changes( |
30 | 32 | ordering => ordering, |
31 | 33 | }); |
32 | 34 |
|
33 | | - let mut last_index = 0; |
34 | | - let mut final_text = String::new(); |
35 | | - |
36 | | - for (i, change) in changes.iter().enumerate() { |
37 | | - if change.range.start > change.range.end { |
38 | | - panic!( |
39 | | - "Text change had start index {} greater than end index {}.\n\n{:?}", |
40 | | - change.range.start, |
41 | | - change.range.end, |
42 | | - &changes[0..i + 1], |
43 | | - ) |
44 | | - } |
45 | | - if change.range.start < last_index { |
46 | | - panic!("Text changes were overlapping. Past index was {}, but new change had index {}.\n\n{:?}", last_index, change.range.start, &changes[0..i + 1]); |
47 | | - } else if change.range.start > last_index && last_index < source.len() { |
48 | | - final_text.push_str( |
49 | | - &source[last_index..std::cmp::min(source.len(), change.range.start)], |
50 | | - ); |
| 35 | + StringBuilder::build(|builder| { |
| 36 | + let mut last_index = 0; |
| 37 | + for (i, change) in changes.iter().enumerate() { |
| 38 | + if change.range.start > change.range.end { |
| 39 | + panic!( |
| 40 | + "Text change had start index {} greater than end index {}.\n\n{:?}", |
| 41 | + change.range.start, |
| 42 | + change.range.end, |
| 43 | + &changes[0..i + 1], |
| 44 | + ) |
| 45 | + } |
| 46 | + if change.range.start < last_index { |
| 47 | + panic!("Text changes were overlapping. Past index was {}, but new change had index {}.\n\n{:?}", last_index, change.range.start, &changes[0..i + 1]); |
| 48 | + } else if change.range.start > last_index && last_index < source.len() { |
| 49 | + builder.append( |
| 50 | + &source[last_index..std::cmp::min(source.len(), change.range.start)], |
| 51 | + ); |
| 52 | + } |
| 53 | + builder.append(&change.new_text); |
| 54 | + last_index = change.range.end; |
51 | 55 | } |
52 | | - final_text.push_str(&change.new_text); |
53 | | - last_index = change.range.end; |
54 | | - } |
55 | 56 |
|
56 | | - if last_index < source.len() { |
57 | | - final_text.push_str(&source[last_index..]); |
58 | | - } |
59 | | - |
60 | | - final_text |
| 57 | + if last_index < source.len() { |
| 58 | + builder.append(&source[last_index..]); |
| 59 | + } |
| 60 | + }).unwrap() |
61 | 61 | } |
62 | 62 |
|
63 | 63 | #[cfg(test)] |
|
0 commit comments