Skip to content

Commit 141c773

Browse files
authored
feat: implement default methods for SpooledTempFile Read/Write (#232)
That way we can take advantage of, e.g., vectorized operations.
1 parent 3590dbf commit 141c773

File tree

1 file changed

+47
-5
lines changed

1 file changed

+47
-5
lines changed

src/spooled.rs

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,43 @@ impl Read for SpooledTempFile {
122122
SpooledData::OnDisk(file) => file.read(buf),
123123
}
124124
}
125+
126+
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
127+
match &mut self.inner {
128+
SpooledData::InMemory(cursor) => cursor.read_vectored(bufs),
129+
SpooledData::OnDisk(file) => file.read_vectored(bufs),
130+
}
131+
}
132+
133+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
134+
match &mut self.inner {
135+
SpooledData::InMemory(cursor) => cursor.read_to_end(buf),
136+
SpooledData::OnDisk(file) => file.read_to_end(buf),
137+
}
138+
}
139+
140+
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
141+
match &mut self.inner {
142+
SpooledData::InMemory(cursor) => cursor.read_to_string(buf),
143+
SpooledData::OnDisk(file) => file.read_to_string(buf),
144+
}
145+
}
146+
147+
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
148+
match &mut self.inner {
149+
SpooledData::InMemory(cursor) => cursor.read_exact(buf),
150+
SpooledData::OnDisk(file) => file.read_exact(buf),
151+
}
152+
}
125153
}
126154

127155
impl Write for SpooledTempFile {
128156
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
129157
// roll over to file if necessary
130-
let mut rolling = false;
131-
if let SpooledData::InMemory(cursor) = &mut self.inner {
132-
rolling = cursor.position() as usize + buf.len() > self.max_size;
133-
}
134-
if rolling {
158+
if matches! {
159+
&self.inner, SpooledData::InMemory(cursor)
160+
if cursor.position() as usize + buf.len() > self.max_size
161+
} {
135162
self.roll()?;
136163
}
137164

@@ -142,6 +169,21 @@ impl Write for SpooledTempFile {
142169
}
143170
}
144171

172+
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
173+
if matches! {
174+
&self.inner, SpooledData::InMemory(cursor)
175+
// Borrowed from the rust standard library.
176+
if cursor.position() as usize + bufs.iter()
177+
.fold(0usize, |a, b| a.saturating_add(b.len())) > self.max_size
178+
} {
179+
self.roll()?;
180+
}
181+
match &mut self.inner {
182+
SpooledData::InMemory(cursor) => cursor.write_vectored(bufs),
183+
SpooledData::OnDisk(file) => file.write_vectored(bufs),
184+
}
185+
}
186+
145187
#[inline]
146188
fn flush(&mut self) -> io::Result<()> {
147189
match &mut self.inner {

0 commit comments

Comments
 (0)