Skip to main content

dsf/
storage.rs

1use std::fs::File;
2use std::io::{self, Cursor, Read, Seek, Write};
3
4mod sealed {
5    pub trait Sealed {}
6    impl Sealed for std::fs::File {}
7    impl Sealed for std::io::Cursor<Vec<u8>> {}
8}
9
10/// A seekable, resizable byte store: a [`File`] or an in-memory buffer.
11///
12/// Sealed so new methods can be added without a breaking change.
13pub trait Storage: Read + Write + Seek + sealed::Sealed {
14    /// Truncates or extends the store to `len` bytes.
15    fn set_len(&mut self, len: u64) -> io::Result<()>;
16    /// Flushes buffered data to durable storage where applicable.
17    fn sync(&mut self) -> io::Result<()>;
18}
19
20impl Storage for File {
21    fn set_len(&mut self, len: u64) -> io::Result<()> {
22        File::set_len(self, len)
23    }
24    fn sync(&mut self) -> io::Result<()> {
25        self.sync_all()
26    }
27}
28
29impl Storage for Cursor<Vec<u8>> {
30    fn set_len(&mut self, len: u64) -> io::Result<()> {
31        let len = usize::try_from(len)
32            .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "length exceeds usize"))?;
33        self.get_mut().resize(len, 0);
34        Ok(())
35    }
36    fn sync(&mut self) -> io::Result<()> {
37        Ok(())
38    }
39}