start_storage/
lib.rs

1use std::{error::Error, fs::{File, OpenOptions}, ops::{Index, IndexMut}, path::PathBuf};
2
3use memmap2::MmapMut;
4
5type HandleResult<T> = Result<T, Box<dyn Error>>;
6
7pub enum StartStorage {     
8    InMemory(Vec<u8>),
9    Mapped {
10        path: PathBuf,
11        mmap: MmapMut
12    }
13}
14
15impl StartStorage {
16    pub fn len(&self) -> usize {
17        match self {
18            StartStorage::InMemory(vec) => vec.len(),
19            StartStorage::Mapped { mmap, .. } => mmap.len(),
20        }
21    }
22
23    pub fn resize(&mut self, new_len: usize) -> HandleResult<()> {
24        match self {
25            StartStorage::InMemory(vec) => {
26                vec.resize(new_len, 0);
27            },
28            StartStorage::Mapped { mmap, path } => {
29                let file = OpenOptions::new()
30                    .read(true)
31                    .write(true)
32                    .create(true)
33                    .open(&path)?;
34                file.set_len(new_len as u64)?;
35
36                let new_mmap = unsafe { MmapMut::map_mut(&file) }?;
37                *mmap = new_mmap;
38            },
39        }
40        Ok(())
41    }
42
43    pub fn in_memory() -> Self {
44        Self::InMemory(vec![])
45    }
46
47    pub fn embedded(path: PathBuf) -> HandleResult<Self> {
48        let file = OpenOptions::new()
49            .read(true)
50            .write(true)
51            .create(true)
52            .open(&path)?;
53        let mmap = unsafe { MmapMut::map_mut(&file) }?;
54        Ok(Self::Mapped { path, mmap })
55    }
56}
57
58impl Index<std::ops::Range<usize>> for StartStorage {
59    type Output = [u8];
60
61    fn index(&self, range: std::ops::Range<usize>) -> &Self::Output {
62        match &self {
63            StartStorage::InMemory(vec) => &vec[range],
64            StartStorage::Mapped{ path: _, mmap } => &mmap[range],
65        }
66    }
67}
68
69impl IndexMut<std::ops::Range<usize>> for StartStorage {
70    fn index_mut(&mut self, range: std::ops::Range<usize>) -> &mut Self::Output {
71        match self {
72            StartStorage::InMemory(vec) => &mut vec[range],
73            StartStorage::Mapped { mmap, .. } => &mut mmap[range],
74        }
75    }
76}