playdate_fs/
api.rs

1use core::ffi::c_int;
2use core::ffi::c_uint;
3use core::ffi::c_char;
4use core::ffi::c_void;
5use core::ptr::NonNull;
6
7use sys::ffi::playdate_file;
8use sys::ffi::FileOptions;
9use sys::ffi::FileStat;
10
11
12/// Default file system api end-point, ZST.
13///
14/// All calls approximately costs ~3 derefs.
15#[derive(Debug, Clone, Copy, core::default::Default)]
16pub struct Default;
17impl Api for Default {}
18
19
20/// Cached file system api end-point.
21///
22/// Useful if you're making many operations on fs.
23///
24/// Stores one reference, so size on stack is eq `usize`.
25///
26/// All calls approximately costs ~1 deref.
27#[derive(Clone, Copy)]
28#[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
29pub struct Cache(&'static playdate_file);
30
31impl core::default::Default for Cache {
32	fn default() -> Self { Self(sys::api!(file)) }
33}
34
35impl From<*const playdate_file> for Cache {
36	#[inline(always)]
37	fn from(ptr: *const playdate_file) -> Self { Self(unsafe { ptr.as_ref() }.expect("fs")) }
38}
39
40impl From<&'static playdate_file> for Cache {
41	#[inline(always)]
42	fn from(r: &'static playdate_file) -> Self { Self(r) }
43}
44
45impl From<NonNull<playdate_file>> for Cache {
46	#[inline(always)]
47	fn from(ptr: NonNull<playdate_file>) -> Self { Self(unsafe { ptr.as_ref() }) }
48}
49
50impl From<&'_ NonNull<playdate_file>> for Cache {
51	#[inline(always)]
52	fn from(ptr: &NonNull<playdate_file>) -> Self { Self(unsafe { ptr.as_ref() }) }
53}
54
55
56impl Api for Cache {
57	#[inline(always)]
58	fn close(&self) -> defs::FnClose { self.0.close.expect("close") }
59
60	#[inline(always)]
61	fn flush(&self) -> defs::FnFlush { self.0.flush.expect("flush") }
62
63	#[inline(always)]
64	fn geterr(&self) -> defs::FnGeterr { self.0.geterr.expect("geterr") }
65
66	#[inline(always)]
67	fn listfiles(&self) -> defs::FnListfiles { self.0.listfiles.expect("listfiles") }
68
69	#[inline(always)]
70	fn mkdir(&self) -> defs::FnMkdir { self.0.mkdir.expect("mkdir") }
71
72	#[inline(always)]
73	fn open(&self) -> defs::FnOpen { self.0.open.expect("open") }
74
75	#[inline(always)]
76	fn read(&self) -> defs::FnRead { self.0.read.expect("read") }
77
78	#[inline(always)]
79	fn rename(&self) -> defs::FnRename { self.0.rename.expect("rename") }
80
81	#[inline(always)]
82	fn seek(&self) -> defs::FnSeek { self.0.seek.expect("seek") }
83
84	#[inline(always)]
85	fn stat(&self) -> defs::FnStat { self.0.stat.expect("stat") }
86
87	#[inline(always)]
88	fn tell(&self) -> defs::FnTell { self.0.tell.expect("tell") }
89
90	#[inline(always)]
91	fn unlink(&self) -> defs::FnUnlink { self.0.unlink.expect("unlink") }
92
93	#[inline(always)]
94	fn write(&self) -> defs::FnWrite { self.0.write.expect("write") }
95}
96
97
98pub trait Api {
99	/// Returns [`sys::ffi::playdate_file::close`].
100	#[doc(alias = "sys::ffi::playdate_file::close")]
101	#[inline(always)]
102	fn close(&self) -> defs::FnClose { *sys::api!(file.close) }
103
104	/// Returns [`sys::ffi::playdate_file::flush`].
105	#[doc(alias = "sys::ffi::playdate_file::flush")]
106	#[inline(always)]
107	fn flush(&self) -> defs::FnFlush { *sys::api!(file.flush) }
108
109	/// Returns [`sys::ffi::playdate_file::geterr`].
110	#[doc(alias = "sys::ffi::playdate_file::geterr")]
111	#[inline(always)]
112	fn geterr(&self) -> defs::FnGeterr { *sys::api!(file.geterr) }
113
114	/// Returns [`sys::ffi::playdate_file::listfiles`].
115	#[doc(alias = "sys::ffi::playdate_file::listfiles")]
116	#[inline(always)]
117	fn listfiles(&self) -> defs::FnListfiles { *sys::api!(file.listfiles) }
118
119	/// Returns [`sys::ffi::playdate_file::mkdir`].
120	#[doc(alias = "sys::ffi::playdate_file::mkdir")]
121	#[inline(always)]
122	fn mkdir(&self) -> defs::FnMkdir { *sys::api!(file.mkdir) }
123
124	/// Returns [`sys::ffi::playdate_file::open`].
125	#[doc(alias = "sys::ffi::playdate_file::open")]
126	#[inline(always)]
127	fn open(&self) -> defs::FnOpen { *sys::api!(file.open) }
128
129	/// Returns [`sys::ffi::playdate_file::read`].
130	#[doc(alias = "sys::ffi::playdate_file::read")]
131	#[inline(always)]
132	fn read(&self) -> defs::FnRead { *sys::api!(file.read) }
133
134	/// Returns [`sys::ffi::playdate_file::rename`].
135	#[doc(alias = "sys::ffi::playdate_file::rename")]
136	#[inline(always)]
137	fn rename(&self) -> defs::FnRename { *sys::api!(file.rename) }
138
139	/// Returns [`sys::ffi::playdate_file::seek`].
140	#[doc(alias = "sys::ffi::playdate_file::seek")]
141	#[inline(always)]
142	fn seek(&self) -> defs::FnSeek { *sys::api!(file.seek) }
143
144	/// Returns [`sys::ffi::playdate_file::stat`].
145	#[doc(alias = "sys::ffi::playdate_file::stat")]
146	#[inline(always)]
147	fn stat(&self) -> defs::FnStat { *sys::api!(file.stat) }
148
149	/// Returns [`sys::ffi::playdate_file::tell`].
150	#[doc(alias = "sys::ffi::playdate_file::tell")]
151	#[inline(always)]
152	fn tell(&self) -> defs::FnTell { *sys::api!(file.tell) }
153
154	/// Returns [`sys::ffi::playdate_file::unlink`].
155	#[doc(alias = "sys::ffi::playdate_file::unlink")]
156	#[inline(always)]
157	fn unlink(&self) -> defs::FnUnlink { *sys::api!(file.unlink) }
158
159	/// Returns [`sys::ffi::playdate_file::write`].
160	#[doc(alias = "sys::ffi::playdate_file::write")]
161	#[inline(always)]
162	fn write(&self) -> defs::FnWrite { *sys::api!(file.write) }
163}
164
165impl<T: Api> Api for &'_ T {
166	#[inline(always)]
167	fn close(&self) -> defs::FnClose { (*self).close() }
168
169	#[inline(always)]
170	fn flush(&self) -> defs::FnFlush { (*self).flush() }
171
172	#[inline(always)]
173	fn geterr(&self) -> defs::FnGeterr { (*self).geterr() }
174
175	#[inline(always)]
176	fn listfiles(&self) -> defs::FnListfiles { (*self).listfiles() }
177
178	#[inline(always)]
179	fn mkdir(&self) -> defs::FnMkdir { (*self).mkdir() }
180
181	#[inline(always)]
182	fn open(&self) -> defs::FnOpen { (*self).open() }
183
184	#[inline(always)]
185	fn read(&self) -> defs::FnRead { (*self).read() }
186
187	#[inline(always)]
188	fn rename(&self) -> defs::FnRename { (*self).rename() }
189
190	#[inline(always)]
191	fn seek(&self) -> defs::FnSeek { (*self).seek() }
192
193	#[inline(always)]
194	fn stat(&self) -> defs::FnStat { (*self).stat() }
195
196	#[inline(always)]
197	fn tell(&self) -> defs::FnTell { (*self).tell() }
198
199	#[inline(always)]
200	fn unlink(&self) -> defs::FnUnlink { (*self).unlink() }
201
202	#[inline(always)]
203	fn write(&self) -> defs::FnWrite { (*self).write() }
204}
205
206
207#[doc(hidden)]
208mod defs {
209	#![doc(hidden)]
210	use super::*;
211
212	pub type FnClose = unsafe extern "C" fn(*mut c_void) -> c_int;
213	pub type FnFlush = unsafe extern "C" fn(*mut c_void) -> c_int;
214	pub type FnGeterr = unsafe extern "C" fn() -> *const c_char;
215	pub type FnListfiles = unsafe extern "C" fn(*const c_char,
216	                                            Option<unsafe extern "C" fn(*const c_char, *mut c_void)>,
217	                                            *mut c_void,
218	                                            c_int) -> c_int;
219	pub type FnMkdir = unsafe extern "C" fn(*const c_char) -> c_int;
220	pub type FnOpen = unsafe extern "C" fn(*const c_char, FileOptions) -> *mut c_void;
221	pub type FnRead = unsafe extern "C" fn(*mut c_void, *mut c_void, c_uint) -> c_int;
222	pub type FnRename = unsafe extern "C" fn(*const c_char, *const c_char) -> c_int;
223	pub type FnSeek = unsafe extern "C" fn(*mut c_void, c_int, c_int) -> c_int;
224	pub type FnStat = unsafe extern "C" fn(*const c_char, *mut FileStat) -> c_int;
225	pub type FnTell = unsafe extern "C" fn(*mut c_void) -> c_int;
226	pub type FnUnlink = unsafe extern "C" fn(*const c_char, c_int) -> c_int;
227	pub type FnWrite = unsafe extern "C" fn(*mut c_void, *const c_void, c_uint) -> c_int;
228}