Skip to content

Commit 9648a33

Browse files
committed
refactor: Cow is better
1 parent c999a75 commit 9648a33

File tree

4 files changed

+56
-59
lines changed

4 files changed

+56
-59
lines changed

src/concat_source.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ impl<'a> StreamChunks<'a> for ConcatSource {
159159
}
160160
let mut current_line_offset = 0;
161161
let mut current_column_offset = 0;
162-
let mut source_mapping: HashMap<String, u32> = HashMap::default();
162+
let mut source_mapping: HashMap<Cow<str>, u32> = HashMap::default();
163163
let mut name_mapping: HashMap<&str, u32> = HashMap::default();
164164
let mut need_to_close_mapping = false;
165165

@@ -262,10 +262,10 @@ impl<'a> StreamChunks<'a> for ConcatSource {
262262
}
263263
},
264264
&mut |i, source, source_content| {
265-
let mut global_index = source_mapping.get(source).copied();
265+
let mut global_index = source_mapping.get(&source).copied();
266266
if global_index.is_none() {
267267
let len = source_mapping.len() as u32;
268-
source_mapping.insert(source.to_owned(), len);
268+
source_mapping.insert(source.clone(), len);
269269
on_source(len, source, source_content);
270270
global_index = Some(len);
271271
}

src/helpers.rs

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub fn get_map<'a, S: StreamChunks<'a>>(
3535
mappings.push(mapping);
3636
},
3737
// on_source
38-
&mut |source_index, source: &str, source_content: Option<&str>| {
38+
&mut |source_index, source, source_content| {
3939
let source_index = source_index as usize;
4040
if sources.len() <= source_index {
4141
sources.resize(source_index + 1, Cow::Borrowed(""));
@@ -49,7 +49,7 @@ pub fn get_map<'a, S: StreamChunks<'a>>(
4949
}
5050
},
5151
// on_name
52-
&mut |name_index, name: &str| {
52+
&mut |name_index, name| {
5353
let name_index = name_index as usize;
5454
if names.len() <= name_index {
5555
names.resize(name_index + 1, Cow::Borrowed(""));
@@ -75,10 +75,10 @@ pub trait StreamChunks<'a> {
7575
}
7676

7777
/// [OnChunk] abstraction, see [webpack-sources onChunk](https://github.com/webpack/webpack-sources/blob/9f98066311d53a153fdc7c633422a1d086528027/lib/helpers/streamChunks.js#L13).
78-
pub type OnChunk<'a, 'b> = &'a mut dyn FnMut(Option<&'b str>, Mapping);
78+
pub type OnChunk<'a, 'b> = &'a mut dyn FnMut(Option<Cow<'b, str>>, Mapping);
7979

8080
/// [OnSource] abstraction, see [webpack-sources onSource](https://github.com/webpack/webpack-sources/blob/9f98066311d53a153fdc7c633422a1d086528027/lib/helpers/streamChunks.js#L13).
81-
pub type OnSource<'a, 'b> = &'a mut dyn FnMut(u32, &str, Option<&'b str>);
81+
pub type OnSource<'a, 'b> = &'a mut dyn FnMut(u32, Cow<'b, str>, Option<&'b str>);
8282

8383
/// [OnName] abstraction, see [webpack-sources onName](https://github.com/webpack/webpack-sources/blob/9f98066311d53a153fdc7c633422a1d086528027/lib/helpers/streamChunks.js#L13).
8484
pub type OnName<'a, 'b> = &'a mut dyn FnMut(u32, &'b str);
@@ -519,7 +519,7 @@ pub fn stream_chunks_of_raw_source<'a>(
519519
let mut last_line = None;
520520
for l in split_into_lines(source) {
521521
on_chunk(
522-
Some(l),
522+
Some(Cow::Borrowed(l)),
523523
Mapping {
524524
generated_line: line,
525525
generated_column: 0,
@@ -580,13 +580,13 @@ pub fn stream_chunks_of_source_map<'a>(
580580
}
581581
}
582582

583-
fn get_source(source_map: &SourceMap, source: &str) -> String {
583+
fn get_source<'a>(source_map: &SourceMap, source: &'a str) -> Cow<'a, str> {
584584
let source_root = source_map.source_root();
585585
match source_root {
586-
Some(root) if root.is_empty() => source.to_string(),
587-
Some(root) if root.ends_with('/') => format!("{}{}", root, source),
588-
Some(root) => format!("{}/{}", root, source),
589-
None => source.to_string(),
586+
Some(root) if root.is_empty() => Cow::Borrowed(source),
587+
Some(root) if root.ends_with('/') => Cow::Owned(format!("{}{}", root, source)),
588+
Some(root) => Cow::Owned(format!("{}/{}", root, source)),
589+
None => Cow::Borrowed(source),
590590
}
591591
}
592592

@@ -604,7 +604,7 @@ fn stream_chunks_of_source_map_final<'a>(
604604
for (i, source) in source_map.sources().iter().enumerate() {
605605
on_source(
606606
i as u32,
607-
&get_source(source_map, source),
607+
get_source(source_map, source),
608608
source_map.get_source_content(i),
609609
)
610610
}
@@ -656,7 +656,7 @@ fn stream_chunks_of_source_map_full<'a>(
656656
for (i, source) in source_map.sources().iter().enumerate() {
657657
on_source(
658658
i as u32,
659-
&get_source(source_map, source),
659+
get_source(source_map, source),
660660
source_map.get_source_content(i),
661661
)
662662
}
@@ -684,7 +684,7 @@ fn stream_chunks_of_source_map_full<'a>(
684684
let chunk = &source[tracking_generated_index..current_generated_index];
685685
if !chunk.is_empty() {
686686
on_chunk(
687-
Some(chunk),
687+
Some(Cow::Borrowed(chunk)),
688688
Mapping {
689689
generated_line: tracking_generated_line,
690690
generated_column: tracking_generated_column,
@@ -710,7 +710,7 @@ fn stream_chunks_of_source_map_full<'a>(
710710
let chunk =
711711
&source[tracking_generated_index..current_generated_index + 1];
712712
on_chunk(
713-
Some(chunk),
713+
Some(Cow::Borrowed(chunk)),
714714
Mapping {
715715
generated_line: tracking_generated_line,
716716
generated_column: tracking_generated_column,
@@ -732,7 +732,7 @@ fn stream_chunks_of_source_map_full<'a>(
732732
if tracking_generated_index < source.len() {
733733
let chunk = &source[tracking_generated_index..];
734734
on_chunk(
735-
Some(chunk),
735+
Some(Cow::Borrowed(chunk)),
736736
Mapping {
737737
generated_line: tracking_generated_line,
738738
generated_column: tracking_generated_column,
@@ -764,7 +764,7 @@ fn stream_chunks_of_source_map_lines_final<'a>(
764764
for (i, source) in source_map.sources().iter().enumerate() {
765765
on_source(
766766
i as u32,
767-
&get_source(source_map, source),
767+
get_source(source_map, source),
768768
source_map.get_source_content(i),
769769
)
770770
}
@@ -819,7 +819,7 @@ fn stream_chunks_of_source_map_lines_full<'a>(
819819
for (i, source) in source_map.sources().iter().enumerate() {
820820
on_source(
821821
i as u32,
822-
&get_source(source_map, source),
822+
get_source(source_map, source),
823823
source_map.get_source_content(i),
824824
)
825825
}
@@ -833,8 +833,9 @@ fn stream_chunks_of_source_map_lines_full<'a>(
833833
}
834834
while mapping.generated_line > current_generated_line {
835835
if current_generated_line as usize <= lines.len() {
836+
let chunk = lines[current_generated_line as usize - 1];
836837
on_chunk(
837-
Some(lines[current_generated_line as usize - 1]),
838+
Some(Cow::Borrowed(chunk)),
838839
Mapping {
839840
generated_line: current_generated_line,
840841
generated_column: 0,
@@ -848,8 +849,9 @@ fn stream_chunks_of_source_map_lines_full<'a>(
848849
.original
849850
.filter(|_| mapping.generated_line as usize <= lines.len())
850851
{
852+
let chunk = lines[current_generated_line as usize - 1];
851853
on_chunk(
852-
Some(lines[mapping.generated_line as usize - 1]),
854+
Some(Cow::Borrowed(chunk)),
853855
Mapping {
854856
generated_line: mapping.generated_line,
855857
generated_column: 0,
@@ -868,8 +870,9 @@ fn stream_chunks_of_source_map_lines_full<'a>(
868870
on_mapping(mapping);
869871
}
870872
while current_generated_line as usize <= lines.len() {
873+
let chunk = lines[current_generated_line as usize - 1];
871874
on_chunk(
872-
Some(lines[current_generated_line as usize - 1]),
875+
Some(Cow::Borrowed(chunk)),
873876
Mapping {
874877
generated_line: current_generated_line,
875878
generated_column: 0,
@@ -900,24 +903,26 @@ struct SourceMapLineData<'a> {
900903

901904
#[derive(Debug)]
902905
struct SourceMapLineChunk<'a> {
903-
content: &'a str,
904-
cached: OnceCell<WithIndices<&'a str>>,
906+
content: Cow<'a, str>,
907+
cached: OnceCell<WithIndices<Cow<'a, str>>>,
905908
}
906909

907910
impl<'a> SourceMapLineChunk<'a> {
908-
pub fn new(content: &'a str) -> Self {
911+
pub fn new(content: Cow<'a, str>) -> Self {
909912
Self {
910913
content,
911914
cached: OnceCell::new(),
912915
}
913916
}
914917

915918
pub fn substring(&self, start_index: usize, end_index: usize) -> &str {
916-
let cached = self.cached.get_or_init(|| WithIndices::new(self.content));
919+
let cached = self.cached.get_or_init(|| WithIndices::new(self.content.clone()));
917920
cached.substring(start_index, end_index)
918921
}
919922
}
920923

924+
type InnerSourceIndexValueMapping<'a> = HashMap<i64, (Cow<'a, str>, Option<&'a str>)>;
925+
921926
#[allow(clippy::too_many_arguments)]
922927
pub fn stream_chunks_of_combined_source_map<'a>(
923928
source: &'a str,
@@ -933,7 +938,7 @@ pub fn stream_chunks_of_combined_source_map<'a>(
933938
) -> GeneratedInfo {
934939
let on_source = RefCell::new(on_source);
935940
let inner_source: RefCell<Option<&str>> = RefCell::new(inner_source);
936-
let source_mapping: RefCell<HashMap<String, u32>> =
941+
let source_mapping: RefCell<HashMap<Cow<str>, u32>> =
937942
RefCell::new(HashMap::default());
938943
let mut name_mapping: HashMap<&str, u32> = HashMap::default();
939944
let source_index_mapping: RefCell<HashMap<i64, i64>> =
@@ -945,9 +950,7 @@ pub fn stream_chunks_of_combined_source_map<'a>(
945950
let inner_source_index: RefCell<i64> = RefCell::new(-2);
946951
let inner_source_index_mapping: RefCell<HashMap<i64, i64>> =
947952
RefCell::new(HashMap::default());
948-
let inner_source_index_value_mapping: RefCell<
949-
HashMap<i64, (String, Option<&str>)>,
950-
> = RefCell::new(HashMap::default());
953+
let inner_source_index_value_mapping: RefCell<InnerSourceIndexValueMapping> = RefCell::new(HashMap::default());
951954
let inner_source_contents: RefCell<HashMap<i64, Option<&str>>> =
952955
RefCell::new(HashMap::default());
953956
let inner_source_content_lines: InnerSourceContentLine =
@@ -1080,11 +1083,11 @@ pub fn stream_chunks_of_combined_source_map<'a>(
10801083
.unwrap_or(("".into(), None));
10811084
let mut source_mapping = source_mapping.borrow_mut();
10821085
let mut global_index =
1083-
source_mapping.get(&source.to_string()).copied();
1086+
source_mapping.get(&source).copied();
10841087
if global_index.is_none() {
10851088
let len = source_mapping.len() as u32;
1086-
source_mapping.insert(source.to_string(), len);
1087-
on_source.borrow_mut()(len, &source, source_content);
1089+
source_mapping.insert(source.clone(), len);
1090+
on_source.borrow_mut()(len, source, source_content);
10881091
global_index = Some(len);
10891092
}
10901093
source_index = global_index.unwrap() as i64;
@@ -1225,7 +1228,7 @@ pub fn stream_chunks_of_combined_source_map<'a>(
12251228
source_mapping.insert(source.into(), len);
12261229
on_source.borrow_mut()(
12271230
len,
1228-
inner_source_name,
1231+
Cow::Borrowed(inner_source_name),
12291232
*inner_source.borrow(),
12301233
);
12311234
global_index = Some(len);
@@ -1360,7 +1363,7 @@ pub fn stream_chunks_of_combined_source_map<'a>(
13601363
inner_source_index_mapping.borrow_mut().insert(i, -2);
13611364
inner_source_index_value_mapping
13621365
.borrow_mut()
1363-
.insert(i, (source.to_string(), source_content));
1366+
.insert(i, (source, source_content));
13641367
},
13651368
&mut |i, name| {
13661369
let i = i as i64;
@@ -1374,10 +1377,10 @@ pub fn stream_chunks_of_combined_source_map<'a>(
13741377
);
13751378
} else {
13761379
let mut source_mapping = source_mapping.borrow_mut();
1377-
let mut global_index = source_mapping.get(source).copied();
1380+
let mut global_index = source_mapping.get(&source).copied();
13781381
if global_index.is_none() {
13791382
let len = source_mapping.len() as u32;
1380-
source_mapping.insert(source.to_string(), len);
1383+
source_mapping.insert(source.clone(), len);
13811384
on_source.borrow_mut()(len, source, source_content);
13821385
global_index = Some(len);
13831386
}

src/original_source.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<'a> StreamChunks<'a> for OriginalSource {
106106
on_source: OnSource<'_, 'a>,
107107
_on_name: OnName,
108108
) -> crate::helpers::GeneratedInfo {
109-
on_source(0, &self.name, Some(&self.value));
109+
on_source(0, Cow::Borrowed(&self.name), Some(&self.value));
110110
if options.columns {
111111
// With column info we need to read all lines and split them
112112
let mut line = 1;
@@ -116,7 +116,7 @@ impl<'a> StreamChunks<'a> for OriginalSource {
116116
if is_end_of_line && token.len() == 1 {
117117
if !options.final_source {
118118
on_chunk(
119-
Some(token),
119+
Some(Cow::Borrowed(token)),
120120
Mapping {
121121
generated_line: line,
122122
generated_column: column,
@@ -126,7 +126,7 @@ impl<'a> StreamChunks<'a> for OriginalSource {
126126
}
127127
} else {
128128
on_chunk(
129-
(!options.final_source).then_some(token),
129+
(!options.final_source).then_some(Cow::Borrowed(token)),
130130
Mapping {
131131
generated_line: line,
132132
generated_column: column,
@@ -195,7 +195,7 @@ impl<'a> StreamChunks<'a> for OriginalSource {
195195
let mut last_line = None;
196196
for l in split_into_lines(&self.value) {
197197
on_chunk(
198-
(!options.final_source).then_some(l),
198+
(!options.final_source).then_some(Cow::Borrowed(l)),
199199
Mapping {
200200
generated_line: line,
201201
generated_column: 0,

src/replace_source.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ pub struct ReplaceSource<T> {
4141
replacements: Mutex<Vec<Replacement>>,
4242
/// Whether `replacements` is sorted.
4343
is_sorted: AtomicBool,
44-
remainder: OnceLock<String>,
4544
}
4645

4746
/// Enforce replacement order when two replacement start and end are both equal
@@ -91,7 +90,6 @@ impl<T> ReplaceSource<T> {
9190
inner_source_code: OnceLock::new(),
9291
replacements: Mutex::new(Vec::new()),
9392
is_sorted: AtomicBool::new(true),
94-
remainder: OnceLock::new(),
9593
}
9694
}
9795

@@ -385,7 +383,7 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
385383
let chunk_slice =
386384
&chunk[chunk_pos as usize..(chunk_pos + offset) as usize];
387385
on_chunk(
388-
Some(chunk_slice),
386+
Some(Cow::Owned(chunk_slice.to_string())),
389387
Mapping {
390388
generated_line: line as u32,
391389
generated_column: ((mapping.generated_column as i64)
@@ -457,7 +455,7 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
457455
}
458456
for (m, content_line) in lines.iter().enumerate() {
459457
on_chunk(
460-
Some(content_line),
458+
Some(Cow::Borrowed(content_line)),
461459
Mapping {
462460
generated_line: line as u32,
463461
generated_column: ((mapping.generated_column as i64)
@@ -568,7 +566,7 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
568566
let chunk_slice = if chunk_pos == 0 {
569567
chunk
570568
} else {
571-
&chunk[chunk_pos as usize..]
569+
Cow::Owned(chunk[chunk_pos as usize..].to_string())
572570
};
573571
let line = mapping.generated_line as i64 + generated_line_offset;
574572
on_chunk(
@@ -624,21 +622,18 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
624622
);
625623

626624
// Handle remaining replacements
627-
let remainder = self.remainder.get_or_init(|| {
628-
let mut remainder = String::new();
629-
while i < repls.len() {
630-
remainder += &repls[i].content;
631-
i += 1;
632-
}
633-
remainder
634-
});
625+
let mut remainder = String::new();
626+
while i < repls.len() {
627+
remainder += &repls[i].content;
628+
i += 1;
629+
}
635630

636631
// Insert remaining replacements content split into chunks by lines
637632
let mut line = result.generated_line as i64 + generated_line_offset;
638-
let matches: Vec<&str> = split_into_lines(remainder).collect();
633+
let matches: Vec<&str> = split_into_lines(&remainder).collect();
639634
for (m, content_line) in matches.iter().enumerate() {
640635
on_chunk(
641-
Some(content_line),
636+
Some(Cow::Owned(content_line.to_string())),
642637
Mapping {
643638
generated_line: line as u32,
644639
generated_column: ((result.generated_column as i64)
@@ -684,8 +679,7 @@ impl<T: Source> Clone for ReplaceSource<T> {
684679
inner: self.inner.clone(),
685680
inner_source_code: self.inner_source_code.clone(),
686681
replacements: Mutex::new(self.replacements().clone()),
687-
is_sorted: AtomicBool::new(self.is_sorted.load(Ordering::SeqCst)),
688-
remainder: OnceLock::new(),
682+
is_sorted: AtomicBool::new(self.is_sorted.load(Ordering::SeqCst))
689683
}
690684
}
691685
}

0 commit comments

Comments
 (0)