norfs 0.0.0

Wear-leveling filesystem for embedded systems
Documentation
use crate::{medium::StorageMedium, StorageError};

use super::WriteGranularity;

pub struct RamStorage<const STORAGE_SIZE: usize, const BLOCK_SIZE: usize, const GRANULARITY: usize>
{
    pub(crate) data: [u8; STORAGE_SIZE],
}

impl<const STORAGE_SIZE: usize, const BLOCK_SIZE: usize, const GRANULARITY: usize> Default
    for RamStorage<STORAGE_SIZE, BLOCK_SIZE, GRANULARITY>
{
    fn default() -> Self {
        Self::new()
    }
}

impl<const STORAGE_SIZE: usize, const BLOCK_SIZE: usize, const GRANULARITY: usize>
    RamStorage<STORAGE_SIZE, BLOCK_SIZE, GRANULARITY>
{
    pub const fn new() -> Self {
        Self {
            data: [0xFF; STORAGE_SIZE],
        }
    }

    fn offset(block: usize, offset: usize) -> usize {
        block * Self::BLOCK_SIZE + offset
    }

    #[cfg(test)]
    pub fn debug_print(&self) {
        for blk in 0..Self::BLOCK_COUNT {
            print!("{blk:02X}:");

            for byte in 0..Self::BLOCK_SIZE {
                print!(" {:02X}", self.data[Self::offset(blk, byte)]);
            }

            println!();
        }
    }
}

impl<const STORAGE_SIZE: usize, const BLOCK_SIZE: usize, const GRANULARITY: usize> StorageMedium
    for RamStorage<STORAGE_SIZE, BLOCK_SIZE, GRANULARITY>
{
    const BLOCK_SIZE: usize = BLOCK_SIZE;
    const BLOCK_COUNT: usize = STORAGE_SIZE / BLOCK_SIZE;
    const WRITE_GRANULARITY: WriteGranularity = WriteGranularity::Word(GRANULARITY);

    async fn erase(&mut self, block: usize) -> Result<(), StorageError> {
        let offset = Self::offset(block, 0);

        self.data[offset..offset + Self::BLOCK_SIZE].fill(0xFF);

        Ok(())
    }

    async fn read(
        &mut self,
        block: usize,
        offset: usize,
        data: &mut [u8],
    ) -> Result<(), StorageError> {
        assert!(
            offset + data.len() <= Self::BLOCK_SIZE,
            "{offset} + {} <= {}",
            data.len(),
            Self::BLOCK_SIZE
        );
        let offset = Self::offset(block, offset);

        data.copy_from_slice(&self.data[offset..offset + data.len()]);

        Ok(())
    }

    async fn write(
        &mut self,
        block: usize,
        offset: usize,
        data: &[u8],
    ) -> Result<(), StorageError> {
        assert!(
            offset + data.len() <= Self::BLOCK_SIZE,
            "{offset} + {} <= {}",
            data.len(),
            Self::BLOCK_SIZE
        );
        let offset = Self::offset(block, offset);

        for (src, dst) in data.iter().zip(self.data[offset..].iter_mut()) {
            assert_eq!(*dst, 0xFF);
            *dst = *src;
        }

        Ok(())
    }
}