1#[derive(Debug, PartialEq)]
2#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3pub enum RingFsError {
4 OutOfSpace,
5 FileOverrun,
6 MissingFileLength,
7 InUse,
8 UnrecoverableDisk,
9 FileTooLarge,
10 FileNotFound,
11 FileClosed,
12 NotAligned,
13 OutOfBounds,
14 Unknown,
15}
16
17#[derive(Debug, Clone, Copy)]
18pub enum FileState {
19 Closed,
20 Reader,
21 Writer,
22}
23
24#[derive(Debug, Clone, Copy)]
25pub struct FileDescriptor {
26 pub state: FileState,
27 pub location: u32,
29 pub len: u32,
31 pub offset: u32,
33}
34
35pub trait RingFs<'f> {
36 fn create_file(&'f self) -> Result<RingFsWriter<'f>, RingFsError>;
37 fn file_reader_by_index(&'f self, index: u32) -> Result<RingFsReader<'f>, RingFsError>;
38 fn file_reader_by_location(&'f self, location: u32) -> Result<RingFsReader<'f>, RingFsError>;
39 fn close_file(&self, desc: &mut FileDescriptor);
40 fn write_file(&self, desc: &mut FileDescriptor, data: &[u8]) -> Result<(), RingFsError>;
41 fn read_file(&self, desc: &mut FileDescriptor, data: &mut [u8]) -> Result<u32, RingFsError>;
42}
43
44pub struct RingFsWriter<'f> {
45 fs: &'f dyn RingFs<'f>,
46 desc: FileDescriptor,
47}
48impl Drop for RingFsWriter<'_> {
49 fn drop(&mut self) {
50 self.close();
51 }
52}
53impl<'f> RingFsWriter<'f> {
54 pub fn new(fs: &'f dyn RingFs<'f>, desc: FileDescriptor) -> Self {
55 Self { fs, desc }
56 }
57
58 pub fn close(&mut self) {
59 self.fs.close_file(&mut self.desc);
60 }
61
62 pub fn is_closed(&self) -> bool {
63 self.desc.is_closed()
64 }
65
66 pub fn write(&mut self, data: &[u8]) -> Result<(), RingFsError> {
67 self.fs.write_file(&mut self.desc, data)
68 }
69
70 pub fn location(&self) -> u32 {
71 self.desc.location
72 }
73}
74
75pub struct RingFsReader<'f> {
76 fs: &'f dyn RingFs<'f>,
77 desc: FileDescriptor,
78}
79impl Drop for RingFsReader<'_> {
80 fn drop(&mut self) {
81 self.close();
82 }
83}
84impl<'f> RingFsReader<'f> {
85 pub fn new(fs: &'f dyn RingFs<'f>, desc: FileDescriptor) -> Self {
86 Self { fs, desc }
87 }
88
89 pub fn close(&mut self) {
90 self.fs.close_file(&mut self.desc);
91 }
92
93 pub fn is_closed(&self) -> bool {
94 self.desc.is_closed()
95 }
96
97 pub fn read(&mut self, data: &mut [u8]) -> Result<u32, RingFsError> {
98 self.fs.read_file(&mut self.desc, data)
99 }
100}
101
102impl FileDescriptor {
103 pub fn new_writer() -> Self {
104 Self {
105 state: FileState::Writer,
106 location: 0,
107 len: 0,
108 offset: 0,
109 }
110 }
111
112 pub fn new_reader(location: u32, len: u32) -> Self {
113 Self {
114 state: FileState::Reader,
115 location,
116 len,
117 offset: 0,
118 }
119 }
120
121 pub fn is_closed(&self) -> bool {
122 matches!(self.state, FileState::Closed)
123 }
124
125 pub(crate) fn close(&mut self) {
126 if !self.is_closed() {
127 self.state = FileState::Closed;
128 }
129 }
130}