Skip to main content

littlefs_rust/
ram.rs

1use alloc::vec;
2use alloc::vec::Vec;
3
4use crate::error::Error;
5use crate::storage::Storage;
6
7/// In-memory block device for testing and examples.
8///
9/// Simulates flash: erased blocks are `0xFF`, writes overwrite bytes, and
10/// erase resets a block to `0xFF`. Use with [`Config`](crate::Config) and
11/// [`Filesystem`](crate::Filesystem).
12pub struct RamStorage {
13    data: Vec<u8>,
14    block_size: u32,
15    block_count: u32,
16}
17
18impl RamStorage {
19    /// Create a new RAM-backed storage with the given block geometry.
20    pub fn new(block_size: u32, block_count: u32) -> Self {
21        let size = (block_size as usize)
22            .checked_mul(block_count as usize)
23            .expect("block_size * block_count overflow");
24        Self {
25            data: vec![0xFFu8; size],
26            block_size,
27            block_count,
28        }
29    }
30
31    /// Return the raw storage bytes (for inspection or persistence).
32    pub fn data(&self) -> &[u8] {
33        &self.data
34    }
35
36    pub fn block_size(&self) -> u32 {
37        self.block_size
38    }
39
40    pub fn block_count(&self) -> u32 {
41        self.block_count
42    }
43
44    fn offset(&self, block: u32, off: u32) -> usize {
45        (block as usize) * (self.block_size as usize) + (off as usize)
46    }
47}
48
49impl Storage for RamStorage {
50    fn read(&mut self, block: u32, offset: u32, buf: &mut [u8]) -> Result<(), Error> {
51        let start = self.offset(block, offset);
52        let end = start + buf.len();
53        if end > self.data.len() {
54            return Err(Error::Io);
55        }
56        buf.copy_from_slice(&self.data[start..end]);
57        Ok(())
58    }
59
60    fn write(&mut self, block: u32, offset: u32, data: &[u8]) -> Result<(), Error> {
61        let start = self.offset(block, offset);
62        let end = start + data.len();
63        if end > self.data.len() {
64            return Err(Error::Io);
65        }
66        self.data[start..end].copy_from_slice(data);
67        Ok(())
68    }
69
70    fn erase(&mut self, block: u32) -> Result<(), Error> {
71        let start = self.offset(block, 0);
72        let end = start + self.block_size as usize;
73        if end > self.data.len() {
74            return Err(Error::Io);
75        }
76        self.data[start..end].fill(0xFF);
77        Ok(())
78    }
79}