Skip to content

Commit 3e74c85

Browse files
committed
feat: add to_writer api to Source trait for better file write performance
closes #41
1 parent 1969fb3 commit 3e74c85

File tree

8 files changed

+54
-0
lines changed

8 files changed

+54
-0
lines changed

src/cached_source.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> Source for CachedSource<T> {
9696
map
9797
}
9898
}
99+
100+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
101+
self.inner.to_writer(writer)
102+
}
99103
}
100104

101105
impl<T: Source + Hash + PartialEq + Eq + 'static> StreamChunks

src/concat_source.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ impl Source for ConcatSource {
9999
fn map(&self, options: &MapOptions) -> Option<SourceMap> {
100100
get_map(self, options)
101101
}
102+
103+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
104+
for child in &self.children {
105+
child.to_writer(writer)?;
106+
}
107+
Ok(())
108+
}
102109
}
103110

104111
impl Hash for ConcatSource {

src/original_source.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ impl Source for OriginalSource {
6666
fn map(&self, options: &MapOptions) -> Option<SourceMap> {
6767
get_map(self, options)
6868
}
69+
70+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
71+
writer.write_all(self.value.as_bytes())
72+
}
6973
}
7074

7175
impl Hash for OriginalSource {

src/raw_source.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ impl Source for RawSource {
8888
fn map(&self, _: &MapOptions) -> Option<SourceMap> {
8989
None
9090
}
91+
92+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
93+
writer.write_all(match self {
94+
RawSource::Buffer(i) => i,
95+
RawSource::Source(i) => i.as_bytes(),
96+
})
97+
}
9198
}
9299

93100
impl Hash for RawSource {

src/replace_source.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> Source for ReplaceSource<T> {
141141
drop(replacements);
142142
get_map(self, options)
143143
}
144+
145+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
146+
writer.write_all(self.source().as_bytes())
147+
}
144148
}
145149

146150
impl<T: Source> StreamChunks for ReplaceSource<T> {

src/source.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ pub trait Source:
3737
fn update_hash(&self, state: &mut dyn Hasher) {
3838
self.dyn_hash(state);
3939
}
40+
41+
/// Writes the source into a writer, preferably a `std::io::BufWriter<std::io::Write>`.
42+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()>;
4043
}
4144

4245
impl Source for Box<dyn Source> {
@@ -55,6 +58,10 @@ impl Source for Box<dyn Source> {
5558
fn map(&self, options: &MapOptions) -> Option<SourceMap> {
5659
self.as_ref().map(options)
5760
}
61+
62+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
63+
self.as_ref().to_writer(writer)
64+
}
5865
}
5966

6067
dyn_clone::clone_trait_object!(Source);
@@ -615,4 +622,17 @@ mod tests {
615622
map.insert(a, a);
616623
assert_eq!(map.get(&a).unwrap(), &a);
617624
}
625+
626+
#[test]
627+
fn to_writer() {
628+
let sources =
629+
ConcatSource::new([RawSource::from("a"), RawSource::from("b")]);
630+
let mut writer = std::io::BufWriter::new(Vec::new());
631+
let result = sources.to_writer(&mut writer);
632+
assert!(result.is_ok());
633+
assert_eq!(
634+
String::from_utf8(writer.into_inner().unwrap()).unwrap(),
635+
"ab"
636+
);
637+
}
618638
}

src/source_map_source.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ impl Source for SourceMapSource {
106106
}
107107
get_map(self, options)
108108
}
109+
110+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
111+
writer.write_all(self.value.as_bytes())
112+
}
109113
}
110114

111115
impl Hash for SourceMapSource {

tests/compat_source.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ impl Source for CompatSource {
2727
fn map(&self, _options: &MapOptions) -> Option<SourceMap> {
2828
self.1.clone()
2929
}
30+
31+
fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
32+
writer.write_all(self.0.as_bytes())
33+
}
3034
}
3135

3236
impl StreamChunks for CompatSource {

0 commit comments

Comments
 (0)