stak_file/file_system/
memory.rs1use super::utility::decode_path;
2use crate::{FileDescriptor, FileError, FileSystem};
3use heapless::Vec;
4use stak_vm::{Memory, Value};
5
6const PATH_SIZE: usize = 128;
7
8#[derive(Clone, Copy, Debug)]
9pub struct MemoryFileEntry {
10 file_index: usize,
11 offset: usize,
12}
13
14#[derive(Debug)]
16pub struct MemoryFileSystem<'a> {
17 files: &'a [(&'a [u8], &'a [u8])],
18 entries: &'a mut [Option<MemoryFileEntry>],
19}
20
21impl<'a> MemoryFileSystem<'a> {
22 pub const fn new(
24 files: &'a [(&'a [u8], &'a [u8])],
25 entries: &'a mut [Option<MemoryFileEntry>],
26 ) -> Self {
27 Self { files, entries }
28 }
29}
30
31impl FileSystem for MemoryFileSystem<'_> {
32 type Path = [u8];
33 type PathBuf = Vec<u8, PATH_SIZE>;
34 type Error = FileError;
35
36 fn open(&mut self, path: &Self::Path, output: bool) -> Result<FileDescriptor, Self::Error> {
37 if output {
38 return Err(FileError::Open);
39 }
40
41 for (file_index, (file_path, _)) in self.files.iter().enumerate() {
42 if path == *file_path {
43 for (descriptor, entry) in self.entries.iter_mut().enumerate() {
44 if entry.is_none() {
45 *entry = Some(MemoryFileEntry {
46 file_index,
47 offset: 0,
48 });
49
50 return Ok(descriptor);
51 }
52 }
53 }
54 }
55
56 Err(FileError::Open)
57 }
58
59 fn close(&mut self, descriptor: FileDescriptor) -> Result<(), Self::Error> {
60 let Some(entry) = self.entries.get_mut(descriptor) else {
61 return Err(FileError::Close);
62 };
63
64 *entry = None;
65
66 Ok(())
67 }
68
69 fn read(&mut self, descriptor: FileDescriptor) -> Result<Option<u8>, Self::Error> {
70 let entry = &mut self
71 .entries
72 .get_mut(descriptor)
73 .and_then(Option::as_mut)
74 .ok_or(FileError::Read)?;
75
76 let Some(&byte) = self
77 .files
78 .get(entry.file_index)
79 .ok_or(FileError::Read)?
80 .1
81 .get(entry.offset)
82 else {
83 return Ok(None);
84 };
85
86 entry.offset += 1;
87
88 Ok(Some(byte))
89 }
90
91 fn write(&mut self, _: FileDescriptor, _: u8) -> Result<(), Self::Error> {
92 Err(FileError::Write)
93 }
94
95 fn delete(&mut self, _: &Self::Path) -> Result<(), Self::Error> {
96 Err(FileError::Delete)
97 }
98
99 fn flush(&mut self, _: FileDescriptor) -> Result<(), Self::Error> {
100 Err(FileError::Flush)
101 }
102
103 fn exists(&self, path: &Self::Path) -> Result<bool, Self::Error> {
104 for (file_path, _) in self.files {
105 if &path == file_path {
106 return Ok(true);
107 }
108 }
109
110 Ok(false)
111 }
112
113 fn decode_path(memory: &Memory, list: Value) -> Result<Self::PathBuf, Self::Error> {
114 decode_path(memory, list).ok_or(FileError::PathDecode)
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn create_file_system() {
124 MemoryFileSystem::new(&[], &mut []);
125 }
126
127 #[test]
128 fn read() {
129 let mut entries = [Default::default(); 8];
130 let mut system = MemoryFileSystem::new(&[(b"foo", b"bar")], &mut entries);
131
132 let descriptor = system.open(b"foo", false).unwrap();
133
134 assert_eq!(system.read(descriptor), Ok(Some(b'b')));
135 assert_eq!(system.read(descriptor), Ok(Some(b'a')));
136 assert_eq!(system.read(descriptor), Ok(Some(b'r')));
137 assert_eq!(system.read(descriptor), Ok(None));
138
139 system.close(descriptor).unwrap();
140
141 assert!(system.read(descriptor).is_err());
142 }
143
144 #[test]
145 fn exists() {
146 let mut entries = [Default::default(); 8];
147 let system = MemoryFileSystem::new(&[(b"foo", b"bar")], &mut entries);
148
149 assert!(system.exists(b"foo").unwrap());
150 assert!(!system.exists(b"bar").unwrap());
151 }
152}