Skip to content

Commit ce63252

Browse files
Turn serialization::BackingStorage into enum instead of a trait with two impls.
1 parent 40a26b6 commit ce63252

File tree

1 file changed

+54
-27
lines changed

1 file changed

+54
-27
lines changed

measureme/src/serialization.rs

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,49 @@ pub struct SerializationSink {
2020
}
2121

2222
/// The `BackingStorage` is what the data gets written to.
23-
trait BackingStorage: Write + Send + Debug {
23+
#[derive(Debug)]
24+
enum BackingStorage {
25+
File(fs::File),
26+
Memory(Vec<u8>),
27+
}
28+
29+
impl BackingStorage {
2430
/// Moves all data written so far out into a `Vec<u8>`. This method only
2531
/// exists so we can write unit tests that don't need to touch the
26-
/// file system. The method is allowed to unconditionally panic for
27-
/// non-test implementations.
28-
fn drain_bytes(&mut self) -> Vec<u8>;
32+
/// file system. The method will panic if `self` is `BackingStorage::Memory`.
33+
fn into_bytes(self) -> Vec<u8> {
34+
match self {
35+
BackingStorage::File(_) => {
36+
panic!("into_bytes() is not supported for BackingStorage::File")
37+
}
38+
BackingStorage::Memory(data) => data,
39+
}
40+
}
2941
}
3042

31-
impl BackingStorage for fs::File {
32-
fn drain_bytes(&mut self) -> Vec<u8> {
33-
unimplemented!()
43+
impl Write for BackingStorage {
44+
#[inline]
45+
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
46+
match *self {
47+
BackingStorage::File(ref mut file) => file.write(buf),
48+
BackingStorage::Memory(ref mut vec) => vec.write(buf),
49+
}
3450
}
35-
}
3651

37-
impl BackingStorage for Vec<u8> {
38-
fn drain_bytes(&mut self) -> Vec<u8> {
39-
let mut bytes = Vec::new();
40-
std::mem::swap(&mut bytes, self);
41-
bytes
52+
fn flush(&mut self) -> std::io::Result<()> {
53+
match *self {
54+
BackingStorage::File(ref mut file) => file.flush(),
55+
BackingStorage::Memory(_) => {
56+
// Nothing to do
57+
Ok(())
58+
}
59+
}
4260
}
4361
}
4462

4563
#[derive(Debug)]
4664
struct Inner {
47-
file: Box<dyn BackingStorage>,
65+
file: BackingStorage,
4866
buffer: Vec<u8>,
4967
buf_pos: usize,
5068
addr: u32,
@@ -54,7 +72,7 @@ impl SerializationSink {
5472
pub fn new_in_memory() -> SerializationSink {
5573
SerializationSink {
5674
data: Mutex::new(Inner {
57-
file: Box::new(Vec::new()),
75+
file: BackingStorage::Memory(Vec::new()),
5876
buffer: vec![0; 1024 * 512],
5977
buf_pos: 0,
6078
addr: 0,
@@ -65,21 +83,30 @@ impl SerializationSink {
6583
/// Create a copy of all data written so far. This method meant to be used
6684
/// for writing unit tests. It will panic if the underlying `BackingStorage`
6785
/// does not implement `extract_bytes`.
68-
pub fn into_bytes(self) -> Vec<u8> {
69-
let mut data = self.data.lock();
86+
pub fn into_bytes(mut self) -> Vec<u8> {
87+
// Swap out the contains of `self` with something that can safely be
88+
// dropped without side effects.
89+
let mut data = Mutex::new(Inner {
90+
file: BackingStorage::Memory(Vec::new()),
91+
buffer: Vec::new(),
92+
buf_pos: 0,
93+
addr: 0,
94+
});
95+
std::mem::swap(&mut self.data, &mut data);
96+
97+
// Extract the data from the mutex.
7098
let Inner {
71-
ref mut file,
72-
ref mut buffer,
73-
ref mut buf_pos,
99+
mut file,
100+
buffer,
101+
buf_pos,
74102
addr: _,
75-
} = *data;
103+
} = data.into_inner();
76104

77-
// We need to flush the buffer first.
78-
file.write_all(&buffer[..*buf_pos]).unwrap();
79-
*buf_pos = 0;
105+
// Flush the buffer, so all data written so far is in `file`.
106+
file.write_all(&buffer[..buf_pos]).unwrap();
80107

81-
// Then we can create a copy of the data written so far.
82-
file.drain_bytes()
108+
// Then extract the actual bytes.
109+
file.into_bytes()
83110
}
84111

85112
pub fn from_path(path: &Path) -> Result<Self, Box<dyn Error + Send + Sync>> {
@@ -89,7 +116,7 @@ impl SerializationSink {
89116

90117
Ok(SerializationSink {
91118
data: Mutex::new(Inner {
92-
file: Box::new(file),
119+
file: BackingStorage::File(file),
93120
buffer: vec![0; 1024 * 512],
94121
buf_pos: 0,
95122
addr: 0,

0 commit comments

Comments
 (0)