1use crate::{medium::StorageMedium, StorageError};
2
3use super::WriteGranularity;
4
5pub struct RamStorage<const STORAGE_SIZE: usize, const BLOCK_SIZE: usize, const GRANULARITY: usize>
6{
7 pub(crate) data: [u8; STORAGE_SIZE],
8}
9
10impl<const STORAGE_SIZE: usize, const BLOCK_SIZE: usize, const GRANULARITY: usize> Default
11 for RamStorage<STORAGE_SIZE, BLOCK_SIZE, GRANULARITY>
12{
13 fn default() -> Self {
14 Self::new()
15 }
16}
17
18impl<const STORAGE_SIZE: usize, const BLOCK_SIZE: usize, const GRANULARITY: usize>
19 RamStorage<STORAGE_SIZE, BLOCK_SIZE, GRANULARITY>
20{
21 pub const fn new() -> Self {
22 Self {
23 data: [0xFF; STORAGE_SIZE],
24 }
25 }
26
27 fn offset(block: usize, offset: usize) -> usize {
28 block * Self::BLOCK_SIZE + offset
29 }
30
31 #[cfg(test)]
32 pub fn debug_print(&self) {
33 for blk in 0..Self::BLOCK_COUNT {
34 print!("{blk:02X}:");
35
36 for byte in 0..Self::BLOCK_SIZE {
37 print!(" {:02X}", self.data[Self::offset(blk, byte)]);
38 }
39
40 println!();
41 }
42 }
43}
44
45impl<const STORAGE_SIZE: usize, const BLOCK_SIZE: usize, const GRANULARITY: usize> StorageMedium
46 for RamStorage<STORAGE_SIZE, BLOCK_SIZE, GRANULARITY>
47{
48 const BLOCK_SIZE: usize = BLOCK_SIZE;
49 const BLOCK_COUNT: usize = STORAGE_SIZE / BLOCK_SIZE;
50 const WRITE_GRANULARITY: WriteGranularity = WriteGranularity::Word(GRANULARITY);
51
52 async fn erase(&mut self, block: usize) -> Result<(), StorageError> {
53 let offset = Self::offset(block, 0);
54
55 self.data[offset..offset + Self::BLOCK_SIZE].fill(0xFF);
56
57 Ok(())
58 }
59
60 async fn read(
61 &mut self,
62 block: usize,
63 offset: usize,
64 data: &mut [u8],
65 ) -> Result<(), StorageError> {
66 assert!(
67 offset + data.len() <= Self::BLOCK_SIZE,
68 "{offset} + {} <= {}",
69 data.len(),
70 Self::BLOCK_SIZE
71 );
72 let offset = Self::offset(block, offset);
73
74 data.copy_from_slice(&self.data[offset..offset + data.len()]);
75
76 Ok(())
77 }
78
79 async fn write(
80 &mut self,
81 block: usize,
82 offset: usize,
83 data: &[u8],
84 ) -> Result<(), StorageError> {
85 assert!(
86 offset + data.len() <= Self::BLOCK_SIZE,
87 "{offset} + {} <= {}",
88 data.len(),
89 Self::BLOCK_SIZE
90 );
91 let offset = Self::offset(block, offset);
92
93 for (src, dst) in data.iter().zip(self.data[offset..].iter_mut()) {
94 assert_eq!(*dst, 0xFF);
95 *dst = *src;
96 }
97
98 Ok(())
99 }
100}