1#![cfg_attr(not(test), no_std)]
2
3extern crate sys;
5extern crate alloc;
6
7use core::ffi::c_char;
8use alloc::borrow::ToOwned;
9
10use sys::ffi::CStr;
11use sys::ffi::CString;
12use sys::ffi::lua_CFunction;
13
14
15pub mod error;
16
17use error::*;
18
19#[derive(Debug, Clone, Copy)]
20pub struct Lua<Api = api::Default>(Api);
21
22impl Lua<api::Default> {
23 #[allow(non_snake_case)]
27 pub fn Default() -> Self { Self(Default::default()) }
28}
29
30impl Lua<api::Cache> {
31 #[allow(non_snake_case)]
35 pub fn Cached() -> Self { Self(Default::default()) }
36}
37
38impl<Api: Default + api::Api> Default for Lua<Api> {
39 fn default() -> Self { Self(Default::default()) }
40}
41
42impl<Api: Default + api::Api> Lua<Api> {
43 pub fn new() -> Self { Self(Default::default()) }
44}
45
46impl<Api: api::Api> Lua<Api> {
47 pub fn new_with(api: Api) -> Self { Self(api) }
48}
49
50
51impl Lua<api::Default> {}
52
53
54impl<Api: api::Api> Lua<Api> {
55 #[doc(alias = "sys::ffi::playdate_lua::addFunction")]
61 pub fn add_function<S: AsRef<str>>(&self, f: lua_CFunction, name: S) -> Result<(), ApiError> {
62 let name = CString::new(name.as_ref())?;
63 let mut out_err: *const c_char = core::ptr::null_mut();
64
65 let func = self.0.add_function();
66
67 let result = unsafe { func(f, name.as_ptr(), &mut out_err) };
69
70 if result == 0 {
71 let err_msg = unsafe { CStr::from_ptr(out_err) };
72 Err(Error::AddFunction(err_msg.to_owned()).into())
73 } else {
74 Ok(())
75 }
76 }
77
78 #[doc(alias = "sys::ffi::playdate_lua::getArgString")]
82 pub fn get_arg_string(&self, pos: i32) -> Option<CString> {
83 let f = self.0.get_arg_string();
84 unsafe {
85 let ptr = f(pos);
86 if ptr.is_null() {
87 None
88 } else {
89 Some(CStr::from_ptr(ptr).to_owned())
90 }
91 }
92 }
93}
94
95pub mod api {
96 use core::ffi::c_char;
97 use core::ffi::c_int;
98 use core::ptr::NonNull;
99 use sys::ffi::lua_CFunction;
100 use sys::ffi::playdate_lua;
101
102
103 #[derive(Debug, Clone, Copy, core::default::Default)]
107 pub struct Default;
108 impl Api for Default {}
109
110
111 #[derive(Clone, Copy)]
117 #[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
118 pub struct Cache(&'static playdate_lua);
119
120 impl core::default::Default for Cache {
121 fn default() -> Self { Self(sys::api!(lua)) }
122 }
123
124 impl From<*const playdate_lua> for Cache {
125 #[inline(always)]
126 fn from(ptr: *const playdate_lua) -> Self { Self(unsafe { ptr.as_ref() }.expect("lua")) }
127 }
128
129 impl From<&'static playdate_lua> for Cache {
130 #[inline(always)]
131 fn from(r: &'static playdate_lua) -> Self { Self(r) }
132 }
133
134 impl From<NonNull<playdate_lua>> for Cache {
135 #[inline(always)]
136 fn from(ptr: NonNull<playdate_lua>) -> Self { Self(unsafe { ptr.as_ref() }) }
137 }
138
139 impl From<&'_ NonNull<playdate_lua>> for Cache {
140 #[inline(always)]
141 fn from(ptr: &NonNull<playdate_lua>) -> Self { Self(unsafe { ptr.as_ref() }) }
142 }
143
144
145 impl Api for Cache {
146 #[inline(always)]
147 fn add_function(
148 &self)
149 -> unsafe extern "C" fn(f: lua_CFunction, name: *const c_char, outErr: *mut *const c_char) -> c_int {
150 self.0.addFunction.expect("addFunction")
151 }
152
153 #[inline(always)]
154 fn get_arg_string(&self) -> unsafe extern "C" fn(pos: c_int) -> *const c_char {
155 self.0.getArgString.expect("getArgString")
156 }
157 }
158
159
160 pub trait Api {
161 #[doc(alias = "sys::ffi::playdate_lua::addFunction")]
163 fn add_function(
164 &self)
165 -> unsafe extern "C" fn(f: lua_CFunction, name: *const c_char, outErr: *mut *const c_char) -> c_int {
166 *sys::api!(lua.addFunction)
167 }
168 #[doc(alias = "sys::ffi::playdate_lua::getArgString")]
170 fn get_arg_string(&self) -> unsafe extern "C" fn(pos: c_int) -> *const c_char {
171 *sys::api!(lua.getArgString)
172 }
173 }
174}