1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
use std::ffi::{CStr, CString}; use std::mem; use td_clua; use td_clua::lua_State; use libc; use LuaRead; use LuaPush; macro_rules! integer_impl( ($t:ident) => ( impl LuaPush for $t { fn push_to_lua(self, lua: *mut lua_State) -> i32 { unsafe { td_clua::lua_pushinteger(lua, self as td_clua::lua_Integer) }; 1 } } impl LuaRead for $t { fn lua_read_with_pop(lua: *mut lua_State, index: i32, _pop: i32) -> Option<$t> { let mut success = unsafe { mem::uninitialized() }; let val = unsafe { td_clua::lua_tointegerx(lua, index, &mut success) }; match success { 0 => None, _ => Some(val as $t) } } } ); ); integer_impl!(i8); integer_impl!(i16); integer_impl!(i32); integer_impl!(i64); integer_impl!(u8); integer_impl!(u16); integer_impl!(u32); integer_impl!(u64); integer_impl!(usize); macro_rules! numeric_impl( ($t:ident) => ( impl LuaPush for $t { fn push_to_lua(self, lua: *mut lua_State) -> i32 { unsafe { td_clua::lua_pushnumber(lua, self as f64) }; 1 } } impl LuaRead for $t { fn lua_read_with_pop(lua: *mut lua_State, index: i32, _pop: i32) -> Option<$t> { let mut success = unsafe { mem::uninitialized() }; let val = unsafe { td_clua::lua_tonumberx(lua, index, &mut success) }; match success { 0 => None, _ => Some(val as $t) } } } ); ); numeric_impl!(f32); numeric_impl!(f64); impl LuaPush for String { fn push_to_lua(self, lua: *mut lua_State) -> i32 { if let Some(value) = CString::new(&self[..]).ok() { unsafe { td_clua::lua_pushstring(lua, value.as_ptr()) }; 1 } else { let value = CString::new(&"UNVAILED STRING"[..]).unwrap(); unsafe { td_clua::lua_pushstring(lua, value.as_ptr()) }; 1 } } } impl LuaRead for String { fn lua_read_with_pop(lua: *mut lua_State, index: i32, _pop: i32) -> Option<String> { let mut size: libc::size_t = unsafe { mem::uninitialized() }; let c_str_raw = unsafe { td_clua::lua_tolstring(lua, index, &mut size) }; if c_str_raw.is_null() { return None; } let c_str = unsafe { CStr::from_ptr(c_str_raw) }; let c_str = String::from_utf8_lossy(c_str.to_bytes()); Some(c_str.to_string()) } } impl<'s> LuaPush for &'s str { fn push_to_lua(self, lua: *mut lua_State) -> i32 { let value = CString::new(&self[..]).unwrap(); unsafe { td_clua::lua_pushstring(lua, value.as_ptr()) }; 1 } } impl LuaPush for bool { fn push_to_lua(self, lua: *mut lua_State) -> i32 { unsafe { td_clua::lua_pushboolean(lua, self.clone() as libc::c_int) }; 1 } } impl LuaRead for bool { fn lua_read_with_pop(lua: *mut lua_State, index: i32, _pop: i32) -> Option<bool> { if unsafe { td_clua::lua_isboolean(lua, index) } != true { return None; } Some(unsafe { td_clua::lua_toboolean(lua, index) != 0 }) } } impl LuaPush for () { fn push_to_lua(self, lua: *mut lua_State) -> i32 { unsafe { td_clua::lua_pushnil(lua) }; 1 } } impl LuaRead for () { fn lua_read_with_pop(_: *mut lua_State, _: i32, _pop: i32) -> Option<()> { Some(()) } }