luars/lua_value/
lua_convert.rs1use crate::lua_value::LuaValue;
28use crate::lua_vm::LuaState;
29
30pub trait FromLua: Sized {
35 fn from_lua(value: LuaValue, state: &LuaState) -> Result<Self, String>;
39}
40
41pub trait IntoLua {
46 fn into_lua(self, state: &mut LuaState) -> Result<usize, String>;
50}
51
52impl FromLua for LuaValue {
55 #[inline]
56 fn from_lua(value: LuaValue, _state: &LuaState) -> Result<Self, String> {
57 Ok(value)
58 }
59}
60
61impl IntoLua for LuaValue {
62 #[inline]
63 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
64 state.push_value(self).map_err(|e| format!("{:?}", e))?;
65 Ok(1)
66 }
67}
68
69impl FromLua for () {
72 #[inline]
73 fn from_lua(_value: LuaValue, _state: &LuaState) -> Result<Self, String> {
74 Ok(())
75 }
76}
77
78impl IntoLua for () {
79 #[inline]
80 fn into_lua(self, _state: &mut LuaState) -> Result<usize, String> {
81 Ok(0)
82 }
83}
84
85impl FromLua for bool {
88 #[inline]
89 fn from_lua(value: LuaValue, _state: &LuaState) -> Result<Self, String> {
90 Ok(value.as_boolean().unwrap_or(!value.is_nil()))
92 }
93}
94
95impl IntoLua for bool {
96 #[inline]
97 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
98 state
99 .push_value(LuaValue::boolean(self))
100 .map_err(|e| format!("{:?}", e))?;
101 Ok(1)
102 }
103}
104
105macro_rules! impl_from_lua_int {
108 ($($ty:ty),*) => {
109 $(
110 impl FromLua for $ty {
111 #[inline]
112 fn from_lua(value: LuaValue, _state: &LuaState) -> Result<Self, String> {
113 if let Some(i) = value.as_integer() {
114 Ok(i as $ty)
115 } else if let Some(f) = value.as_float() {
116 Ok(f as $ty)
117 } else {
118 Err(format!("expected integer, got {}", value.type_name()))
119 }
120 }
121 }
122
123 impl IntoLua for $ty {
124 #[inline]
125 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
126 state
127 .push_value(LuaValue::integer(self as i64))
128 .map_err(|e| format!("{:?}", e))?;
129 Ok(1)
130 }
131 }
132 )*
133 };
134}
135
136impl_from_lua_int!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
137
138macro_rules! impl_from_lua_float {
141 ($($ty:ty),*) => {
142 $(
143 impl FromLua for $ty {
144 #[inline]
145 fn from_lua(value: LuaValue, _state: &LuaState) -> Result<Self, String> {
146 if let Some(n) = value.as_number() {
147 Ok(n as $ty)
148 } else if let Some(i) = value.as_integer() {
149 Ok(i as $ty)
150 } else {
151 Err(format!("expected number, got {}", value.type_name()))
152 }
153 }
154 }
155
156 impl IntoLua for $ty {
157 #[inline]
158 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
159 state
160 .push_value(LuaValue::float(self as f64))
161 .map_err(|e| format!("{:?}", e))?;
162 Ok(1)
163 }
164 }
165 )*
166 };
167}
168
169impl_from_lua_float!(f32, f64);
170
171impl FromLua for String {
174 #[inline]
175 fn from_lua(value: LuaValue, _state: &LuaState) -> Result<Self, String> {
176 if let Some(s) = value.as_str() {
177 Ok(s.to_owned())
178 } else if let Some(i) = value.as_integer() {
179 Ok(format!("{}", i))
181 } else if let Some(f) = value.as_float() {
182 Ok(format!("{}", f))
183 } else {
184 Err(format!("expected string, got {}", value.type_name()))
185 }
186 }
187}
188
189impl IntoLua for String {
190 #[inline]
191 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
192 let s = state.create_string(&self).map_err(|e| format!("{:?}", e))?;
193 state.push_value(s).map_err(|e| format!("{:?}", e))?;
194 Ok(1)
195 }
196}
197
198impl IntoLua for &str {
199 #[inline]
200 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
201 let s = state.create_string(self).map_err(|e| format!("{:?}", e))?;
202 state.push_value(s).map_err(|e| format!("{:?}", e))?;
203 Ok(1)
204 }
205}
206
207impl<T: FromLua> FromLua for Option<T> {
210 #[inline]
211 fn from_lua(value: LuaValue, state: &LuaState) -> Result<Self, String> {
212 if value.is_nil() {
213 Ok(None)
214 } else {
215 T::from_lua(value, state).map(Some)
216 }
217 }
218}
219
220impl<T: IntoLua> IntoLua for Option<T> {
221 #[inline]
222 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
223 match self {
224 Some(v) => v.into_lua(state),
225 None => {
226 state
227 .push_value(LuaValue::nil())
228 .map_err(|e| format!("{:?}", e))?;
229 Ok(1)
230 }
231 }
232 }
233}
234
235impl<T: IntoLua, E: std::fmt::Display> IntoLua for Result<T, E> {
238 #[inline]
239 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
240 match self {
241 Ok(v) => v.into_lua(state),
242 Err(e) => Err(format!("{}", e)),
243 }
244 }
245}
246
247impl<T: IntoLua> IntoLua for Vec<T> {
250 #[inline]
251 fn into_lua(self, state: &mut LuaState) -> Result<usize, String> {
252 let count = self.len();
253 for item in self {
254 item.into_lua(state)?;
255 }
256 Ok(count)
257 }
258}