1#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5#[cfg(feature = "alloc")]
6use alloc::vec;
7use firefly_rust::*;
8
9#[cfg(feature = "alloc")]
10pub struct DirBuf {
11 raw: Box<[u8]>,
12}
13
14#[cfg(feature = "alloc")]
15impl DirBuf {
16 #[must_use]
18 pub fn list_dirs(name: &str) -> Self {
19 let size = Dir::list_dirs_buf_size(name);
20 let mut buf = vec![0; size];
21 Dir::list_dirs(name, &mut buf);
22 Self {
23 raw: buf.into_boxed_slice(),
24 }
25 }
26
27 #[must_use]
29 pub fn list_files(name: &str) -> Self {
30 let size = Dir::list_files_buf_size(name);
31 let mut buf = vec![0; size];
32 Dir::list_files(name, &mut buf);
33 Self {
34 raw: buf.into_boxed_slice(),
35 }
36 }
37
38 #[must_use]
40 pub fn iter(&self) -> DirIter<'_> {
41 DirIter { raw: &self.raw }
42 }
43}
44
45pub struct Dir<'a> {
46 raw: &'a [u8],
47}
48
49impl<'a> Dir<'a> {
50 #[must_use]
51 pub fn list_dirs_buf_size(name: &str) -> usize {
52 let path_ptr = name.as_ptr();
53 let size = unsafe { b::list_dirs_buf_size(path_ptr as u32, name.len() as u32) };
54 size as usize
55 }
56
57 #[must_use]
58 pub fn list_files_buf_size(name: &str) -> usize {
59 let path_ptr = name.as_ptr();
60 let size = unsafe { b::list_files_buf_size(path_ptr as u32, name.len() as u32) };
61 size as usize
62 }
63
64 pub fn list_dirs(name: &str, buf: &'a mut [u8]) -> Self {
65 let path_ptr = name.as_ptr();
66 let buf_ptr = buf.as_mut_ptr();
67 unsafe {
68 b::list_dirs(
69 path_ptr as u32,
70 name.len() as u32,
71 buf_ptr as u32,
72 buf.len() as u32,
73 );
74 }
75 Self { raw: buf }
76 }
77
78 pub fn list_files(name: &str, buf: &'a mut [u8]) -> Self {
79 let path_ptr = name.as_ptr();
80 let buf_ptr = buf.as_mut_ptr();
81 unsafe {
82 b::list_files(
83 path_ptr as u32,
84 name.len() as u32,
85 buf_ptr as u32,
86 buf.len() as u32,
87 );
88 }
89 Self { raw: buf }
90 }
91
92 #[must_use]
94 pub const fn iter(&self) -> DirIter<'a> {
95 DirIter { raw: self.raw }
96 }
97}
98
99pub struct DirIter<'a> {
100 raw: &'a [u8],
101}
102
103impl<'a> Iterator for DirIter<'a> {
104 type Item = &'a str;
105
106 fn next(&mut self) -> Option<Self::Item> {
107 let len = self.raw.first()?;
108 let len = *len as usize;
109 let raw_name = self.raw.get(1..=len)?;
110 let name = core::str::from_utf8(raw_name).unwrap_or("");
114 self.raw = self.raw.get((len + 1)..).unwrap_or(&[]);
115 Some(name)
116 }
117}
118
119pub fn run_app(author_id: &str, app_id: &str) {
124 let author_ptr = author_id.as_ptr() as u32;
125 let app_ptr = app_id.as_ptr() as u32;
126 let author_len = author_id.len() as u32;
127 let app_len = app_id.len() as u32;
128 unsafe {
129 b::run_app(author_ptr, author_len, app_ptr, app_len);
130 }
131}
132
133#[must_use]
134pub fn get_file_size(path: &str) -> usize {
135 let path_ptr = path.as_ptr() as u32;
136 let path_len = path.len() as u32;
137 let size = unsafe { b::get_file_size(path_ptr, path_len) };
138 size as usize
139}
140
141pub fn load_file<'a>(path: &str, buf: &'a mut [u8]) -> FileRef<'a> {
146 let path_ptr = path.as_ptr() as u32;
147 let path_len = path.len() as u32;
148 let buf_ptr = buf.as_mut_ptr() as u32;
149 let buf_len = buf.len() as u32;
150 unsafe {
151 b::load_file(path_ptr, path_len, buf_ptr, buf_len);
152 }
153 unsafe { FileRef::from_bytes(buf) }
154}
155
156#[cfg(feature = "alloc")]
160#[must_use]
161pub fn load_file_buf(path: &str) -> Option<FileBuf> {
162 let size = get_file_size(path);
163 if size == 0 {
164 return None;
165 }
166 let mut buf = vec![0u8; size];
167 let path_ptr = path.as_ptr() as u32;
168 let path_len = path.len() as u32;
169 let buf_ptr = buf.as_mut_ptr() as u32;
170 let buf_len = buf.len() as u32;
171 unsafe {
172 b::load_file(path_ptr, path_len, buf_ptr, buf_len);
173 }
174 let buf = buf.into_boxed_slice();
175 Some(unsafe { FileBuf::from_bytes(buf) })
176}
177
178pub fn dump_file(path: &str, buf: &[u8]) {
179 let path_ptr = path.as_ptr() as u32;
180 let path_len = path.len() as u32;
181 let buf_ptr = buf.as_ptr() as u32;
182 let buf_len = buf.len() as u32;
183 unsafe {
184 b::dump_file(path_ptr, path_len, buf_ptr, buf_len);
185 }
186}
187
188pub fn append_file(path: &str, buf: &[u8]) {
189 let path_ptr = path.as_ptr() as u32;
190 let path_len = path.len() as u32;
191 let buf_ptr = buf.as_ptr() as u32;
192 let buf_len = buf.len() as u32;
193 unsafe {
194 b::append_file(path_ptr, path_len, buf_ptr, buf_len);
195 }
196}
197
198pub fn remove_file(path: &str) {
199 let path_ptr = path.as_ptr() as u32;
200 let path_len = path.len() as u32;
201 unsafe {
202 b::remove_file(path_ptr, path_len);
203 }
204}
205
206pub fn remove_dir(path: &str) {
207 let path_ptr = path.as_ptr() as u32;
208 let path_len = path.len() as u32;
209 unsafe {
210 b::remove_dir(path_ptr, path_len);
211 }
212}
213
214pub fn create_dir(path: &str) {
215 let path_ptr = path.as_ptr() as u32;
216 let path_len = path.len() as u32;
217 unsafe {
218 b::create_dir(path_ptr, path_len);
219 }
220}
221
222mod b {
224 #[link(wasm_import_module = "sudo")]
225 unsafe extern "C" {
226 pub(super) fn list_dirs_buf_size(path_ptr: u32, path_len: u32) -> u32;
227 pub(super) fn list_dirs(path_ptr: u32, path_len: u32, buf_ptr: u32, buf_len: u32) -> u32;
228 pub(super) fn list_files_buf_size(path_ptr: u32, path_len: u32) -> u32;
229 pub(super) fn list_files(path_ptr: u32, path_len: u32, buf_ptr: u32, buf_len: u32) -> u32;
230 pub(super) fn run_app(author_ptr: u32, author_len: u32, app_ptr: u32, app_len: u32);
231 pub(super) fn get_file_size(path_ptr: u32, path_len: u32) -> u32;
232 pub(super) fn load_file(path_ptr: u32, path_len: u32, buf_ptr: u32, buf_len: u32) -> u32;
233 pub(super) fn dump_file(path_ptr: u32, path_len: u32, buf_ptr: u32, buf_len: u32) -> u32;
234 pub(super) fn append_file(path_ptr: u32, path_len: u32, buf_ptr: u32, buf_len: u32) -> u32;
235 pub(super) fn remove_file(path_ptr: u32, path_len: u32);
236 pub(super) fn remove_dir(path_ptr: u32, path_len: u32);
237 pub(super) fn create_dir(path_ptr: u32, path_len: u32);
238 }
239}