2017-10-23 16:42:20 -04:00
|
|
|
use std::collections::{BTreeMap, HashMap};
|
2017-10-24 16:15:57 -04:00
|
|
|
use std::hash::{BuildHasher, Hash};
|
2017-07-20 05:33:15 -04:00
|
|
|
use std::string::String as StdString;
|
2017-05-21 19:50:59 -04:00
|
|
|
|
|
|
|
use error::*;
|
2017-10-23 16:42:20 -04:00
|
|
|
use types::{Integer, LightUserData, Number};
|
2017-05-21 19:50:59 -04:00
|
|
|
use lua::*;
|
2017-09-15 16:03:14 -04:00
|
|
|
use string::String;
|
|
|
|
use table::Table;
|
2017-10-23 16:42:20 -04:00
|
|
|
use userdata::{AnyUserData, UserData};
|
2017-05-21 19:50:59 -04:00
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> ToLua<'lua> for Value<'lua> {
|
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
2017-05-21 19:50:59 -04:00
|
|
|
Ok(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> FromLua<'lua> for Value<'lua> {
|
|
|
|
fn from_lua(lua_value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
2017-05-21 19:50:59 -04:00
|
|
|
Ok(lua_value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-20 05:33:15 -04:00
|
|
|
impl<'lua> ToLua<'lua> for String<'lua> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::String(self))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-20 05:33:15 -04:00
|
|
|
impl<'lua> FromLua<'lua> for String<'lua> {
|
|
|
|
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<String<'lua>> {
|
2017-05-21 19:50:59 -04:00
|
|
|
lua.coerce_string(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> ToLua<'lua> for Table<'lua> {
|
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value> {
|
|
|
|
Ok(Value::Table(self))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> FromLua<'lua> for Table<'lua> {
|
|
|
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Table<'lua>> {
|
2017-05-21 19:50:59 -04:00
|
|
|
match value {
|
2017-07-18 16:21:12 -04:00
|
|
|
Value::Table(table) => Ok(table),
|
2017-08-01 13:36:26 -04:00
|
|
|
_ => Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "table",
|
|
|
|
message: None,
|
|
|
|
}),
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> ToLua<'lua> for Function<'lua> {
|
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Function(self))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> FromLua<'lua> for Function<'lua> {
|
|
|
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Function<'lua>> {
|
2017-05-21 19:50:59 -04:00
|
|
|
match value {
|
2017-07-18 16:21:12 -04:00
|
|
|
Value::Function(table) => Ok(table),
|
2017-08-01 13:36:26 -04:00
|
|
|
_ => Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "function",
|
|
|
|
message: None,
|
|
|
|
}),
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> ToLua<'lua> for Thread<'lua> {
|
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Thread(self))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> FromLua<'lua> for Thread<'lua> {
|
|
|
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Thread<'lua>> {
|
2017-05-21 19:50:59 -04:00
|
|
|
match value {
|
2017-07-18 16:21:12 -04:00
|
|
|
Value::Thread(t) => Ok(t),
|
2017-08-01 13:36:26 -04:00
|
|
|
_ => Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "thread",
|
|
|
|
message: None,
|
|
|
|
}),
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> ToLua<'lua> for AnyUserData<'lua> {
|
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::UserData(self))
|
2017-05-24 23:13:58 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> FromLua<'lua> for AnyUserData<'lua> {
|
|
|
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<AnyUserData<'lua>> {
|
2017-05-24 23:13:58 -04:00
|
|
|
match value {
|
2017-07-18 16:21:12 -04:00
|
|
|
Value::UserData(ud) => Ok(ud),
|
2017-08-01 13:36:26 -04:00
|
|
|
_ => Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "userdata",
|
|
|
|
message: None,
|
|
|
|
}),
|
2017-05-24 23:13:58 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua, T: UserData> ToLua<'lua> for T {
|
|
|
|
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
2017-12-03 23:45:00 -05:00
|
|
|
Ok(Value::UserData(lua.create_userdata(self)?))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-29 09:53:37 -04:00
|
|
|
impl<'lua, T: UserData + Clone> FromLua<'lua> for T {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<T> {
|
2017-05-21 19:50:59 -04:00
|
|
|
match value {
|
2017-07-29 09:53:37 -04:00
|
|
|
Value::UserData(ud) => Ok(ud.borrow::<T>()?.clone()),
|
2017-08-01 13:36:26 -04:00
|
|
|
_ => Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "userdata",
|
|
|
|
message: None,
|
|
|
|
}),
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> ToLua<'lua> for Error {
|
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Error(self))
|
2017-06-25 01:47:55 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> FromLua<'lua> for Error {
|
|
|
|
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Error> {
|
2017-06-25 01:47:55 -04:00
|
|
|
match value {
|
2017-07-18 16:21:12 -04:00
|
|
|
Value::Error(err) => Ok(err),
|
|
|
|
val => Ok(Error::RuntimeError(
|
2017-06-25 02:04:14 -04:00
|
|
|
lua.coerce_string(val)
|
|
|
|
.and_then(|s| Ok(s.to_str()?.to_owned()))
|
|
|
|
.unwrap_or_else(|_| "<unprintable error>".to_owned()),
|
|
|
|
)),
|
2017-06-25 01:47:55 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-21 19:50:59 -04:00
|
|
|
impl<'lua> ToLua<'lua> for bool {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Boolean(self))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua> FromLua<'lua> for bool {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(v: Value, _: &'lua Lua) -> Result<Self> {
|
2017-05-21 19:50:59 -04:00
|
|
|
match v {
|
2017-07-18 16:21:12 -04:00
|
|
|
Value::Nil => Ok(false),
|
|
|
|
Value::Boolean(b) => Ok(b),
|
2017-05-21 19:50:59 -04:00
|
|
|
_ => Ok(true),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> ToLua<'lua> for LightUserData {
|
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::LightUserData(self))
|
2017-05-25 00:43:35 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 16:21:12 -04:00
|
|
|
impl<'lua> FromLua<'lua> for LightUserData {
|
2017-08-01 13:36:26 -04:00
|
|
|
fn from_lua(value: Value, _: &'lua Lua) -> Result<Self> {
|
|
|
|
match value {
|
2017-07-18 16:21:12 -04:00
|
|
|
Value::LightUserData(ud) => Ok(ud),
|
2017-08-01 13:36:26 -04:00
|
|
|
_ => Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "light userdata",
|
|
|
|
message: None,
|
|
|
|
}),
|
2017-05-25 00:43:35 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-20 05:33:15 -04:00
|
|
|
impl<'lua> ToLua<'lua> for StdString {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
2017-12-03 23:45:00 -05:00
|
|
|
Ok(Value::String(lua.create_string(&self)?))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-20 05:33:15 -04:00
|
|
|
impl<'lua> FromLua<'lua> for StdString {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
2017-06-18 08:48:45 -04:00
|
|
|
Ok(lua.coerce_string(value)?.to_str()?.to_owned())
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua, 'a> ToLua<'lua> for &'a str {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
2017-12-03 23:45:00 -05:00
|
|
|
Ok(Value::String(lua.create_string(self)?))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! lua_convert_int {
|
|
|
|
($x: ty) => {
|
|
|
|
impl<'lua> ToLua<'lua> for $x {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Integer(self as Integer))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua> FromLua<'lua> for $x {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
2017-05-21 19:50:59 -04:00
|
|
|
Ok(lua.coerce_integer(value)? as $x)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_convert_int!(i8);
|
|
|
|
lua_convert_int!(u8);
|
|
|
|
lua_convert_int!(i16);
|
|
|
|
lua_convert_int!(u16);
|
|
|
|
lua_convert_int!(i32);
|
|
|
|
lua_convert_int!(u32);
|
|
|
|
lua_convert_int!(i64);
|
|
|
|
lua_convert_int!(u64);
|
|
|
|
lua_convert_int!(isize);
|
|
|
|
lua_convert_int!(usize);
|
|
|
|
|
|
|
|
macro_rules! lua_convert_float {
|
|
|
|
($x: ty) => {
|
|
|
|
impl<'lua> ToLua<'lua> for $x {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Number(self as Number))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua> FromLua<'lua> for $x {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
2017-05-21 19:50:59 -04:00
|
|
|
Ok(lua.coerce_number(value)? as $x)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_convert_float!(f32);
|
|
|
|
lua_convert_float!(f64);
|
|
|
|
|
|
|
|
impl<'lua, T: ToLua<'lua>> ToLua<'lua> for Vec<T> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Table(lua.create_sequence_from(self)?))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua, T: FromLua<'lua>> FromLua<'lua> for Vec<T> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
|
|
|
if let Value::Table(table) = value {
|
2017-06-20 19:04:25 -04:00
|
|
|
table.sequence_values().collect()
|
2017-05-21 19:50:59 -04:00
|
|
|
} else {
|
2017-08-01 13:36:26 -04:00
|
|
|
Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "Vec",
|
2017-08-02 07:56:28 -04:00
|
|
|
message: Some("expected table".to_string()),
|
2017-08-01 13:36:26 -04:00
|
|
|
})
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-24 16:15:57 -04:00
|
|
|
impl<'lua, K: Eq + Hash + ToLua<'lua>, V: ToLua<'lua>, S: BuildHasher> ToLua<'lua>
|
|
|
|
for HashMap<K, V, S> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Table(lua.create_table_from(self)?))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-24 16:15:57 -04:00
|
|
|
impl<'lua, K: Eq + Hash + FromLua<'lua>, V: FromLua<'lua>, S: BuildHasher + Default> FromLua<'lua>
|
|
|
|
for HashMap<K, V, S> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
|
|
|
if let Value::Table(table) = value {
|
2017-06-19 02:57:03 -04:00
|
|
|
table.pairs().collect()
|
2017-05-21 19:50:59 -04:00
|
|
|
} else {
|
2017-08-01 13:36:26 -04:00
|
|
|
Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "HashMap",
|
2017-08-02 07:56:28 -04:00
|
|
|
message: Some("expected table".to_string()),
|
2017-08-01 13:36:26 -04:00
|
|
|
})
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua, K: Ord + ToLua<'lua>, V: ToLua<'lua>> ToLua<'lua> for BTreeMap<K, V> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
|
|
|
Ok(Value::Table(lua.create_table_from(self)?))
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua, K: Ord + FromLua<'lua>, V: FromLua<'lua>> FromLua<'lua> for BTreeMap<K, V> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
|
|
|
if let Value::Table(table) = value {
|
2017-06-19 02:57:03 -04:00
|
|
|
table.pairs().collect()
|
2017-05-21 19:50:59 -04:00
|
|
|
} else {
|
2017-08-01 13:36:26 -04:00
|
|
|
Err(Error::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "BTreeMap",
|
2017-08-02 07:56:28 -04:00
|
|
|
message: Some("expected table".to_string()),
|
2017-08-01 13:36:26 -04:00
|
|
|
})
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua, T: ToLua<'lua>> ToLua<'lua> for Option<T> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
2017-05-21 19:50:59 -04:00
|
|
|
match self {
|
|
|
|
Some(val) => val.to_lua(lua),
|
2017-07-24 07:12:52 -04:00
|
|
|
None => Ok(Nil),
|
2017-05-21 19:50:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua, T: FromLua<'lua>> FromLua<'lua> for Option<T> {
|
2017-07-18 16:21:12 -04:00
|
|
|
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
2017-05-21 19:50:59 -04:00
|
|
|
match value {
|
2017-07-24 07:12:52 -04:00
|
|
|
Nil => Ok(None),
|
2017-05-21 19:50:59 -04:00
|
|
|
value => Ok(Some(T::from_lua(value, lua)?)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|