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 132 133 134 135 136 137 138 139 140 141
use {ffi, CheckLua, Error, FromLua, Index, IntoLua, Result, State}; use std::{slice, str}; macro_rules! impl_numbers { ($($type:ty),+) => { $(impl IntoLua for $type { #[inline] unsafe fn into_lua(self, state: &mut State) { ffi::lua_pushinteger(state.pointer, self as _); } })+ $(impl CheckLua for $type { #[inline] unsafe fn check(state: &State, idx: Index) -> bool { ffi::lua_isnumber(state.pointer, idx.as_absolute()) == 1 } })+ $(impl<'a> FromLua<'a> for $type { #[inline] unsafe fn from_lua(state: &'a State, idx: Index) -> Result<Self> { let mut isnum = 0; let res = ffi::lua_tonumberx(state.pointer, idx.as_absolute() as _, &mut isnum); if isnum == 0 { Err(Error::Type) } else { Ok(res as $type) } } })+ } } macro_rules! impl_integers { ($($type:ty),+) => { $(impl IntoLua for $type { #[inline] unsafe fn into_lua(self, state: &mut State) { ffi::lua_pushnumber(state.pointer, self as _); } })+ $(impl CheckLua for $type { #[inline] unsafe fn check(state: &State, idx: Index) -> bool { ffi::lua_isinteger(state.pointer, idx.as_absolute()) == 1 } })+ $(impl<'a> FromLua<'a> for $type { #[inline] unsafe fn from_lua(state: &'a State, idx: Index) -> Result<Self> { let mut isnum = 0; let res = ffi::lua_tointegerx(state.pointer, idx.as_absolute() as _, &mut isnum); if isnum == 0 { Err(Error::Type) } else { Ok(res as $type) } } })+ } } impl_integers!{ i8, i16, i32, i64, isize, i128, u8, u16, u32, u64, usize, u128 } impl_numbers!{ f32, f64 } impl IntoLua for bool { #[inline] unsafe fn into_lua(self, state: &mut State) { if self { ffi::lua_pushboolean(state.pointer, 1); } else { ffi::lua_pushboolean(state.pointer, 0); } } } impl CheckLua for bool { #[inline] unsafe fn check(state: &State, idx: Index) -> bool { ffi::lua_isboolean(state.pointer, idx.as_absolute()) } } impl<'a> FromLua<'a> for bool { #[inline] unsafe fn from_lua(state: &'a State, idx: Index) -> Result<Self> { Ok(ffi::lua_toboolean(state.pointer, idx.as_absolute() as _) == 1) } } macro_rules! impl_string { ($(ref $type:ty),+) => { $(impl<'a> IntoLua for &'a $type { #[inline] unsafe fn into_lua(self, state: &mut State) { ffi::lua_pushlstring(state.pointer, self.as_ptr() as _, self.len() as _); } })+ $(impl CheckLua for $type { #[inline] unsafe fn check(state: &State, idx: Index) -> bool { ffi::lua_isstring(state.pointer, idx.as_absolute()) == 1 } })+ }; ($($type:ty),+) => { $(impl IntoLua for $type { #[inline] unsafe fn into_lua(self, state: &mut State) { ffi::lua_pushlstring(state.pointer, self.as_ptr() as _, self.len() as _); } })+ } } impl_string! { ref str, ref [u8] } impl_string! { String, Vec<u8> } impl<'a> FromLua<'a> for &'a str { unsafe fn from_lua(state: &'a State, idx: Index) -> Result<Self> { let mut len = 0; let ptr = ffi::lua_tolstring(state.pointer, idx.as_absolute(), &mut len); if ptr.is_null() { Err(Error::Type) } else { let slice = slice::from_raw_parts(ptr as *const u8, len); str::from_utf8(slice).map_err(|_| Error::Utf8) } } } impl<'a> FromLua<'a> for &'a [u8] { unsafe fn from_lua(state: &'a State, idx: Index) -> Result<Self> { let mut len = 0; let ptr = ffi::lua_tolstring(state.pointer, idx.as_absolute(), &mut len); if ptr.is_null() { Err(Error::Type) } else { Ok(slice::from_raw_parts(ptr as *const u8, len)) } } }