1use std::{fs::OpenOptions, io::Read, path::Path};
2
3pub fn optional_read_exact<R: Read + ?Sized>(
5 this: &mut R,
6 mut buf: &mut [u8],
7) -> Option<std::io::Result<()>> {
8 let mut read_bytes = 0;
9 while !buf.is_empty() {
10 match this.read(buf) {
11 Ok(0) => break,
12 Ok(n) => {
13 let tmp = buf;
14 buf = &mut tmp[n..];
15 read_bytes += n;
16 }
17 Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {}
18 Err(e) => return Some(Err(e)),
19 }
20 }
21 if read_bytes == 0 {
22 None
23 } else if !buf.is_empty() {
24 Some(Err(std::io::Error::new(
25 std::io::ErrorKind::UnexpectedEof,
26 "buffer partially filled",
27 )))
28 } else {
29 Some(Ok(()))
30 }
31}
32
33pub fn truncate_at(path: &Path, len: u64) -> std::io::Result<()> {
34 let file = OpenOptions::new()
35 .read(false)
36 .write(true)
37 .create(false)
38 .append(false)
39 .open(path)?;
40 file.set_len(len)?;
41 Ok(())
42}