1use crate::*;
4#[cfg(feature = "alloc")]
5use alloc::boxed::Box;
6#[cfg(feature = "alloc")]
7use alloc::vec;
8
9#[cfg(feature = "alloc")]
14pub struct FileBuf {
15 pub(crate) raw: Box<[u8]>,
16}
17
18#[cfg(feature = "alloc")]
19impl FileBuf {
20 #[must_use]
33 pub unsafe fn from_bytes(b: Box<[u8]>) -> Self {
34 Self { raw: b }
35 }
36
37 #[must_use]
38 pub fn into_font(self) -> FontBuf {
39 self.into()
40 }
41
42 #[must_use]
43 pub fn into_image(self) -> ImageBuf {
44 self.into()
45 }
46
47 #[must_use]
48 pub fn into_bytes(self) -> Box<[u8]> {
49 self.into()
50 }
51}
52
53#[cfg(feature = "alloc")]
54impl From<FileBuf> for Box<[u8]> {
55 fn from(value: FileBuf) -> Self {
56 value.raw
57 }
58}
59
60#[cfg(feature = "alloc")]
61impl From<FileBuf> for alloc::vec::Vec<u8> {
62 fn from(value: FileBuf) -> Self {
63 value.raw.into_vec()
64 }
65}
66
67#[cfg(feature = "alloc")]
68impl<'a> From<&'a FileBuf> for &'a [u8] {
69 fn from(value: &'a FileBuf) -> Self {
70 &value.raw
71 }
72}
73
74#[cfg(feature = "alloc")]
75impl TryFrom<FileBuf> for alloc::string::String {
76 type Error = alloc::string::FromUtf8Error;
77
78 fn try_from(value: FileBuf) -> Result<Self, Self::Error> {
79 let v = value.raw.into_vec();
80 alloc::string::String::from_utf8(v)
81 }
82}
83
84pub struct FileRef<'a> {
91 pub(crate) raw: &'a [u8],
92}
93
94impl<'a> FileRef<'a> {
95 #[must_use]
108 pub unsafe fn from_bytes(b: &'a [u8]) -> Self {
109 Self { raw: b }
110 }
111
112 #[must_use]
113 pub fn into_font(self) -> FontRef<'a> {
114 self.into()
115 }
116
117 #[must_use]
118 pub fn into_image(self) -> ImageRef<'a> {
119 self.into()
120 }
121
122 #[must_use]
123 pub fn into_bytes(self) -> &'a [u8] {
124 self.into()
125 }
126}
127
128impl<'a> From<FileRef<'a>> for &'a [u8] {
129 fn from(value: FileRef<'a>) -> Self {
130 value.raw
131 }
132}
133
134#[must_use]
138pub fn get_file_size(name: &str) -> usize {
139 let path_ptr = name.as_ptr();
140 let size = unsafe { bindings::get_file_size(path_ptr as u32, name.len() as u32) };
141 size as usize
142}
143
144pub fn load_file<'a>(name: &str, buf: &'a mut [u8]) -> FileRef<'a> {
149 let path_ptr = name.as_ptr();
150 let buf_ptr = buf.as_mut_ptr();
151 unsafe {
152 bindings::load_file(
153 path_ptr as u32,
154 name.len() as u32,
155 buf_ptr as u32,
156 buf.len() as u32,
157 );
158 }
159 FileRef { raw: buf }
160}
161
162#[cfg(feature = "alloc")]
168#[must_use]
169pub fn load_file_buf(name: &str) -> Option<FileBuf> {
170 let size = get_file_size(name);
171 if size == 0 {
172 return None;
173 }
174 let mut buf = vec![0; size];
175 load_file(name, &mut buf);
176 Some(FileBuf {
177 raw: buf.into_boxed_slice(),
178 })
179}
180
181pub fn dump_file(name: &str, buf: &[u8]) {
186 let path_ptr = name.as_ptr();
187 let buf_ptr = buf.as_ptr();
188 unsafe {
189 bindings::dump_file(
190 path_ptr as u32,
191 name.len() as u32,
192 buf_ptr as u32,
193 buf.len() as u32,
194 );
195 }
196}
197
198pub fn remove_file(name: &str) {
200 let path_ptr = name.as_ptr();
201 unsafe {
202 bindings::remove_file(path_ptr as u32, name.len() as u32);
203 }
204}
205
206mod bindings {
207 #[link(wasm_import_module = "fs")]
208 unsafe extern "C" {
209 pub(crate) unsafe fn get_file_size(path_ptr: u32, path_len: u32) -> u32;
210 pub(crate) unsafe fn load_file(
211 path_ptr: u32,
212 path_len: u32,
213 buf_ptr: u32,
214 buf_len: u32,
215 ) -> u32;
216 pub(crate) unsafe fn dump_file(
217 path_ptr: u32,
218 path_len: u32,
219 buf_ptr: u32,
220 buf_len: u32,
221 ) -> u32;
222 pub(crate) unsafe fn remove_file(path_ptr: u32, path_len: u32);
223 }
224}