seq_data_file/
ioutils.rs

1use std::{fs::OpenOptions, io::Read, path::Path};
2
3/// this is a version of read_exact that returns a None if the stream is empty
4pub 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}