#![cfg_attr(not(test), no_std)]
extern crate sys;
extern crate alloc;
use core::ffi::c_char;
use alloc::borrow::ToOwned;
use sys::ffi::CStr;
use sys::ffi::CString;
use sys::ffi::lua_CFunction;
pub mod error;
use error::*;
#[derive(Debug, Clone, Copy)]
pub struct Lua<Api = api::Default>(Api);
impl Lua<api::Default> {
#[allow(non_snake_case)]
pub fn Default() -> Self { Self(Default::default()) }
}
impl Lua<api::Cache> {
#[allow(non_snake_case)]
pub fn Cached() -> Self { Self(Default::default()) }
}
impl<Api: Default + api::Api> Default for Lua<Api> {
fn default() -> Self { Self(Default::default()) }
}
impl<Api: Default + api::Api> Lua<Api> {
pub fn new() -> Self { Self(Default::default()) }
}
impl<Api: api::Api> Lua<Api> {
pub fn new_with(api: Api) -> Self { Self(api) }
}
impl Lua<api::Default> {}
impl<Api: api::Api> Lua<Api> {
#[doc(alias = "sys::ffi::playdate_lua::addFunction")]
pub fn add_function<S: AsRef<str>>(&self, f: lua_CFunction, name: S) -> Result<(), ApiError> {
let name = CString::new(name.as_ref())?;
let mut out_err: *const c_char = core::ptr::null_mut();
let func = self.0.add_function();
let result = unsafe { func(f, name.as_ptr(), &mut out_err) };
if result == 0 {
let err_msg = unsafe { CStr::from_ptr(out_err) };
Err(Error::AddFunction(err_msg.to_owned()).into())
} else {
Ok(())
}
}
#[doc(alias = "sys::ffi::playdate_lua::getArgString")]
pub fn get_arg_string(&self, pos: i32) -> Option<CString> {
let f = self.0.get_arg_string();
unsafe {
let ptr = f(pos);
if ptr.is_null() {
None
} else {
Some(CStr::from_ptr(ptr).to_owned())
}
}
}
}
pub mod api {
use core::ffi::c_char;
use core::ffi::c_int;
use core::ptr::NonNull;
use sys::ffi::lua_CFunction;
use sys::ffi::playdate_lua;
#[derive(Debug, Clone, Copy, core::default::Default)]
pub struct Default;
impl Api for Default {}
#[derive(Clone, Copy)]
#[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
pub struct Cache(&'static playdate_lua);
impl core::default::Default for Cache {
fn default() -> Self { Self(sys::api!(lua)) }
}
impl From<*const playdate_lua> for Cache {
#[inline(always)]
fn from(ptr: *const playdate_lua) -> Self { Self(unsafe { ptr.as_ref() }.expect("lua")) }
}
impl From<&'static playdate_lua> for Cache {
#[inline(always)]
fn from(r: &'static playdate_lua) -> Self { Self(r) }
}
impl From<NonNull<playdate_lua>> for Cache {
#[inline(always)]
fn from(ptr: NonNull<playdate_lua>) -> Self { Self(unsafe { ptr.as_ref() }) }
}
impl From<&'_ NonNull<playdate_lua>> for Cache {
#[inline(always)]
fn from(ptr: &NonNull<playdate_lua>) -> Self { Self(unsafe { ptr.as_ref() }) }
}
impl Api for Cache {
#[inline(always)]
fn add_function(
&self)
-> unsafe extern "C" fn(f: lua_CFunction, name: *const c_char, outErr: *mut *const c_char) -> c_int {
self.0.addFunction.expect("addFunction")
}
#[inline(always)]
fn get_arg_string(&self) -> unsafe extern "C" fn(pos: c_int) -> *const c_char {
self.0.getArgString.expect("getArgString")
}
}
pub trait Api {
#[doc(alias = "sys::ffi::playdate_lua::addFunction")]
fn add_function(
&self)
-> unsafe extern "C" fn(f: lua_CFunction, name: *const c_char, outErr: *mut *const c_char) -> c_int {
*sys::api!(lua.addFunction)
}
#[doc(alias = "sys::ffi::playdate_lua::getArgString")]
fn get_arg_string(&self) -> unsafe extern "C" fn(pos: c_int) -> *const c_char {
*sys::api!(lua.getArgString)
}
}
}