embedded-storage-file 0.2.0

file and in-memory interface for embedded-storage and embedded-storage-async
Documentation
use crate::synhronous::{BufferBackend, Error, NorMemory};

#[derive(Debug)]
pub struct MmapFile {
    pub file: std::fs::File,
    pub mmap: memmap2::MmapMut,
}

pub type NorMemoryInFile<const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize> =
    NorMemory<MmapFile, READ_SIZE, WRITE_SIZE, ERASE_SIZE>;

impl<const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
    NorMemoryInFile<READ_SIZE, WRITE_SIZE, ERASE_SIZE>
{
    pub fn new<P: std::convert::AsRef<std::path::Path>>(
        path: P,
        size: usize,
    ) -> Result<Self, std::io::Error> {
        let is_new = !path.as_ref().exists();
        let file = std::fs::OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .truncate(false)
            .open(path)?;
        file.set_len(size as u64)?;
        let mut mmap = unsafe { memmap2::MmapOptions::new().map_mut(&file)? };
        if is_new {
            mmap[..size].fill(0xFF);
        }
        Ok(Self {
            buffer: MmapFile { file, mmap },
        })
    }

    pub fn new_from_mmap(mmap: MmapFile) -> Self {
        Self { buffer: mmap }
    }
}

impl BufferBackend for MmapFile {
    fn with_data<F>(&self, from: usize, to: usize, mut f: F) -> Result<(), Error>
    where
        F: FnMut(&[u8]) -> Result<(), Error>,
    {
        if to > self.size() {
            return Err(Error::OutOfBounds);
        }
        if from > to {
            return Err(Error::OutOfBounds);
        }
        let b = &self.mmap[from..to];
        f(b)
    }

    fn with_data_mut<F>(&mut self, from: usize, to: usize, mut f: F) -> Result<(), Error>
    where
        F: FnMut(&mut [u8]) -> Result<(), Error>,
    {
        if to > self.size() {
            return Err(Error::OutOfBounds);
        }
        if from > to {
            return Err(Error::OutOfBounds);
        }
        let b = &mut self.mmap[from..to];
        f(b)
    }

    fn size(&self) -> usize {
        self.mmap.len()
    }
}