Skip to content

Commit c0b3a05

Browse files
authored
Merge pull request #37 from Shnatsel/take_mut
Use take_mut instead of a bespoke unsafe block with mem::replace
2 parents a2971a4 + ffeff7c commit c0b3a05

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ codecov = {repository = "sile/libflate"}
1818
adler32 = "1"
1919
byteorder = "1"
2020
crc32fast = "1"
21+
take_mut = "0.2.2"
2122

2223
[dev-dependencies]
2324
clap = "2"

src/gzip.rs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use byteorder::ReadBytesExt;
2424
use byteorder::WriteBytesExt;
2525
use std::ffi::CString;
2626
use std::io;
27-
use std::mem;
2827
use std::time;
2928

3029
use checksum;
@@ -1118,33 +1117,37 @@ where
11181117
Err(_) => return Ok(0),
11191118
Ok(ref mut decoder) => decoder.read(buf)?,
11201119
};
1120+
// take_mut closure must have the type it borrows as return type,
1121+
// so we put the function return result to this variable instead.
1122+
// If function logic is correct, these initial values will never be returned.
1123+
let mut result: io::Result<usize> = Err(
1124+
io::Error::new(io::ErrorKind::Other, "If you see this error, please report a bug in libflate")
1125+
);
11211126
if read_size == 0 {
1122-
let mut reader = mem::replace(&mut self.decoder, Err(unsafe { mem::uninitialized() }))
1123-
.ok()
1124-
.take()
1125-
.expect("Never fails")
1126-
.into_inner();
1127-
match Header::read_from(&mut reader) {
1128-
Err(e) => {
1129-
mem::forget(mem::replace(&mut self.decoder, Err(reader)));
1130-
if e.kind() == io::ErrorKind::UnexpectedEof {
1131-
Ok(0)
1132-
} else {
1133-
Err(e)
1127+
take_mut::take(self, |mut owned_self| {
1128+
let mut reader = owned_self.decoder.ok().take().expect("Never fails").into_inner();
1129+
match Header::read_from(&mut reader) {
1130+
Err(e) => {
1131+
if e.kind() == io::ErrorKind::UnexpectedEof {
1132+
result = Ok(0);
1133+
} else {
1134+
result = Err(e);
1135+
}
1136+
owned_self.decoder = Err(reader);
1137+
owned_self
1138+
}
1139+
Ok(header) => {
1140+
owned_self.header = header.clone();
1141+
owned_self.decoder = Ok(Decoder::with_header(reader, header));
1142+
result = owned_self.read(buf);
1143+
owned_self
11341144
}
11351145
}
1136-
Ok(header) => {
1137-
self.header = header.clone();
1138-
mem::forget(mem::replace(
1139-
&mut self.decoder,
1140-
Ok(Decoder::with_header(reader, header)),
1141-
));
1142-
self.read(buf)
1143-
}
1144-
}
1146+
})
11451147
} else {
1146-
Ok(read_size)
1148+
result = Ok(read_size);
11471149
}
1150+
result
11481151
}
11491152
}
11501153

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
extern crate adler32;
44
extern crate byteorder;
55
extern crate crc32fast;
6+
extern crate take_mut;
67

78
pub use finish::Finish;
89

0 commit comments

Comments
 (0)