embedded_savegame/
mock.rs1use crate::storage::Flash;
11use core::convert::Infallible;
12
13#[derive(Debug, PartialEq)]
18pub struct MockFlash<const SIZE: usize> {
19 data: [u8; SIZE],
20}
21
22impl<const SIZE: usize> MockFlash<SIZE> {
23 pub const fn new() -> Self {
24 Self { data: [0xFF; SIZE] }
25 }
26}
27
28impl<const SIZE: usize> Default for MockFlash<SIZE> {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl<const SIZE: usize> Flash for MockFlash<SIZE> {
35 type Error = Infallible;
36
37 fn read(&mut self, addr: u32, buf: &mut [u8]) -> Result<(), Self::Error> {
38 let addr = addr as usize;
39 let len = buf.len();
40 buf.copy_from_slice(&self.data[addr..addr + len]);
41 Ok(())
42 }
43
44 fn write(&mut self, addr: u32, data: &mut [u8]) -> Result<(), Self::Error> {
45 let addr = addr as usize;
46 let len = data.len();
47 self.data[addr..addr + len].copy_from_slice(data);
48 Ok(())
49 }
50
51 fn erase(&mut self, addr: u32) -> Result<(), Self::Error> {
52 self.data[addr as usize] = 0xFF;
53 Ok(())
54 }
55}
56
57#[derive(Debug, PartialEq)]
63pub struct SectorMockFlash<const SECTOR_SIZE: usize, const SECTOR_COUNT: usize> {
64 data: [[u8; SECTOR_SIZE]; SECTOR_COUNT],
65}
66
67impl<const SECTOR_SIZE: usize, const SECTOR_COUNT: usize>
68 SectorMockFlash<SECTOR_SIZE, SECTOR_COUNT>
69{
70 pub const fn new() -> Self {
71 Self {
72 data: [[0xFF; SECTOR_SIZE]; SECTOR_COUNT],
73 }
74 }
75
76 fn div_rem(addr: u32) -> (usize, usize) {
77 let addr = addr as usize;
78 let sector = addr / SECTOR_SIZE;
79 let offset = addr % SECTOR_SIZE;
80 (sector, offset)
81 }
82}
83
84impl<const SECTOR_SIZE: usize, const SECTOR_COUNT: usize> Default
85 for SectorMockFlash<SECTOR_SIZE, SECTOR_COUNT>
86{
87 fn default() -> Self {
88 Self::new()
89 }
90}
91
92impl<const SECTOR_SIZE: usize, const SECTOR_COUNT: usize> Flash
93 for SectorMockFlash<SECTOR_SIZE, SECTOR_COUNT>
94{
95 type Error = Infallible;
96
97 fn read(&mut self, addr: u32, buf: &mut [u8]) -> Result<(), Self::Error> {
98 let (sector, offset) = Self::div_rem(addr);
99 buf.copy_from_slice(&self.data[sector][offset..offset + buf.len()]);
100 Ok(())
101 }
102
103 fn write(&mut self, addr: u32, buf: &mut [u8]) -> Result<(), Self::Error> {
104 let (sector, offset) = Self::div_rem(addr);
105
106 let mut flash = self.data[sector][offset..offset + buf.len()].iter_mut();
107 for byte in buf {
108 let flash_byte = flash.next().unwrap();
109 *flash_byte &= *byte;
110 }
111
112 Ok(())
113 }
114
115 fn erase(&mut self, addr: u32) -> Result<(), Self::Error> {
116 let (sector, _offset) = Self::div_rem(addr);
117 self.data[sector] = [0xFF; SECTOR_SIZE];
118 Ok(())
119 }
120}
121
122#[derive(Debug, Default)]
127pub struct MeasuredMockFlash<const SIZE: usize> {
128 flash: MockFlash<SIZE>,
129 pub stats: MeasuredStats,
131}
132
133#[derive(Debug, Default, PartialEq)]
137pub struct MeasuredStats {
138 pub read: usize,
140 pub write: usize,
142 pub erase: usize,
144}
145
146impl<const SIZE: usize> MeasuredMockFlash<SIZE> {
147 pub fn new() -> Self {
148 Self::default()
149 }
150}
151
152impl<const SIZE: usize> Flash for MeasuredMockFlash<SIZE> {
153 type Error = Infallible;
154
155 fn read(&mut self, addr: u32, buf: &mut [u8]) -> Result<(), Self::Error> {
156 self.stats.read = self.stats.read.saturating_add(buf.len());
157 self.flash.read(addr, buf)
158 }
159
160 fn write(&mut self, addr: u32, data: &mut [u8]) -> Result<(), Self::Error> {
161 self.stats.write = self.stats.write.saturating_add(data.len());
162 self.flash.write(addr, data)
163 }
164
165 fn erase(&mut self, addr: u32) -> Result<(), Self::Error> {
166 self.stats.erase = self.stats.erase.saturating_add(1);
167 self.flash.erase(addr)
168 }
169}