1use crate::graphics::*;
4#[cfg(feature = "alloc")]
5use alloc::boxed::Box;
6#[cfg(feature = "alloc")]
7use alloc::vec;
8
9#[cfg(feature = "alloc")]
15pub struct FileBuf {
16 pub(crate) raw: Box<[u8]>,
17}
18
19#[cfg(feature = "alloc")]
20impl FileBuf {
21 #[must_use]
23 pub fn data(&self) -> &[u8] {
24 &self.raw
25 }
26
27 #[must_use]
29 pub fn as_bytes(&self) -> &[u8] {
30 &self.raw
31 }
32
33 #[must_use]
35 pub fn as_font(&'_ self) -> Font<'_> {
36 Font { raw: &self.raw }
37 }
38
39 #[must_use]
41 pub fn as_image(&'_ self) -> Image<'_> {
42 Image { raw: &self.raw }
43 }
44
45 #[must_use]
46 pub fn into_vec(self) -> alloc::vec::Vec<u8> {
47 self.raw.into_vec()
48 }
49}
50
51#[cfg(feature = "alloc")]
52impl From<FileBuf> for Box<[u8]> {
53 fn from(value: FileBuf) -> Self {
54 value.raw
55 }
56}
57
58#[cfg(feature = "alloc")]
59impl From<FileBuf> for alloc::vec::Vec<u8> {
60 fn from(value: FileBuf) -> Self {
61 value.into_vec()
62 }
63}
64
65#[cfg(feature = "alloc")]
66impl TryFrom<FileBuf> for alloc::string::String {
67 type Error = alloc::string::FromUtf8Error;
68
69 fn try_from(value: FileBuf) -> Result<Self, Self::Error> {
70 let v = value.into_vec();
71 alloc::string::String::from_utf8(v)
72 }
73}
74
75pub struct File<'a> {
82 pub(crate) raw: &'a [u8],
83}
84
85impl<'a> File<'a> {
86 #[must_use]
99 pub unsafe fn from_bytes(b: &'a [u8]) -> Self {
100 Self { raw: b }
101 }
102
103 #[must_use]
105 pub const fn data(&self) -> &[u8] {
106 self.raw
107 }
108
109 #[must_use]
111 pub fn as_bytes(&self) -> &[u8] {
112 self.raw
113 }
114
115 #[must_use]
117 pub const fn as_font(&'_ self) -> Font<'_> {
118 Font { raw: self.raw }
119 }
120
121 #[must_use]
123 pub const fn as_image(&'_ self) -> Image<'_> {
124 Image { raw: self.raw }
125 }
126}
127
128#[must_use]
132pub fn get_file_size(name: &str) -> usize {
133 let path_ptr = name.as_ptr();
134 let size = unsafe { bindings::get_file_size(path_ptr as u32, name.len() as u32) };
135 size as usize
136}
137
138pub fn load_file<'a>(name: &str, buf: &'a mut [u8]) -> File<'a> {
143 let path_ptr = name.as_ptr();
144 let buf_ptr = buf.as_mut_ptr();
145 unsafe {
146 bindings::load_file(
147 path_ptr as u32,
148 name.len() as u32,
149 buf_ptr as u32,
150 buf.len() as u32,
151 );
152 }
153 File { raw: buf }
154}
155
156#[cfg(feature = "alloc")]
162#[must_use]
163pub fn load_file_buf(name: &str) -> Option<FileBuf> {
164 let size = get_file_size(name);
165 if size == 0 {
166 return None;
167 }
168 let mut buf = vec![0; size];
169 load_file(name, &mut buf);
170 Some(FileBuf {
171 raw: buf.into_boxed_slice(),
172 })
173}
174
175pub fn dump_file(name: &str, buf: &[u8]) {
180 let path_ptr = name.as_ptr();
181 let buf_ptr = buf.as_ptr();
182 unsafe {
183 bindings::dump_file(
184 path_ptr as u32,
185 name.len() as u32,
186 buf_ptr as u32,
187 buf.len() as u32,
188 );
189 }
190}
191
192pub fn remove_file(name: &str) {
194 let path_ptr = name.as_ptr();
195 unsafe {
196 bindings::remove_file(path_ptr as u32, name.len() as u32);
197 }
198}
199
200mod bindings {
201 #[link(wasm_import_module = "fs")]
202 unsafe extern "C" {
203 pub(crate) fn get_file_size(path_ptr: u32, path_len: u32) -> u32;
204 pub(crate) fn load_file(path_ptr: u32, path_len: u32, buf_ptr: u32, buf_len: u32) -> u32;
205 pub(crate) fn dump_file(path_ptr: u32, path_len: u32, buf_ptr: u32, buf_len: u32) -> u32;
206 pub(crate) fn remove_file(path_ptr: u32, path_len: u32);
207 }
208}