mlua/src/conversion.rs

314 lines
8.9 KiB
Rust
Raw Normal View History

use std::collections::{HashMap, BTreeMap};
2017-05-21 19:50:59 -04:00
use std::hash::Hash;
use error::*;
use lua::*;
impl<'lua> ToLua<'lua> for LuaValue<'lua> {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(self)
}
}
impl<'lua> FromLua<'lua> for LuaValue<'lua> {
fn from_lua(lua_value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
Ok(lua_value)
}
}
impl<'lua> ToLua<'lua> for LuaString<'lua> {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::String(self))
}
}
impl<'lua> FromLua<'lua> for LuaString<'lua> {
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<LuaString<'lua>> {
lua.coerce_string(value)
}
}
impl<'lua> ToLua<'lua> for LuaTable<'lua> {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue> {
Ok(LuaValue::Table(self))
}
}
impl<'lua> FromLua<'lua> for LuaTable<'lua> {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<LuaTable<'lua>> {
match value {
LuaValue::Table(table) => Ok(table),
_ => Err(
LuaConversionError::FromLua("cannot convert lua value to table".to_owned()).into(),
),
2017-05-21 19:50:59 -04:00
}
}
}
impl<'lua> ToLua<'lua> for LuaFunction<'lua> {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::Function(self))
}
}
impl<'lua> FromLua<'lua> for LuaFunction<'lua> {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<LuaFunction<'lua>> {
match value {
LuaValue::Function(table) => Ok(table),
_ => Err(
LuaConversionError::FromLua("cannot convert lua value to function".to_owned())
.into(),
),
2017-05-21 19:50:59 -04:00
}
}
}
impl<'lua> ToLua<'lua> for LuaThread<'lua> {
2017-05-21 19:50:59 -04:00
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::Thread(self))
2017-05-21 19:50:59 -04:00
}
}
impl<'lua> FromLua<'lua> for LuaThread<'lua> {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<LuaThread<'lua>> {
2017-05-21 19:50:59 -04:00
match value {
LuaValue::Thread(t) => Ok(t),
_ => Err(
LuaConversionError::FromLua("cannot convert lua value to thread".to_owned())
.into(),
),
2017-05-21 19:50:59 -04:00
}
}
}
impl<'lua> ToLua<'lua> for LuaUserData<'lua> {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::UserData(self))
}
}
impl<'lua> FromLua<'lua> for LuaUserData<'lua> {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<LuaUserData<'lua>> {
match value {
LuaValue::UserData(ud) => Ok(ud),
_ => Err(
LuaConversionError::FromLua("cannot convert lua value to userdata".to_owned())
.into(),
),
}
}
}
2017-05-21 19:50:59 -04:00
impl<'lua, T: LuaUserDataType> ToLua<'lua> for T {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
lua.create_userdata(self).map(LuaValue::UserData)
}
}
impl<'lua, T: LuaUserDataType + Copy> FromLua<'lua> for T {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<T> {
match value {
LuaValue::UserData(ud) => Ok(*ud.borrow::<T>()?),
_ => Err(
LuaConversionError::FromLua("cannot convert lua value to userdata".to_owned())
.into(),
),
2017-05-21 19:50:59 -04:00
}
}
}
impl<'lua> ToLua<'lua> for LuaError {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::Error(self))
}
}
impl<'lua> FromLua<'lua> for LuaError {
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<LuaError> {
match value {
LuaValue::Error(err) => Ok(err),
val => Ok(LuaError::RuntimeError(
lua.coerce_string(val)
.and_then(|s| Ok(s.to_str()?.to_owned()))
.unwrap_or_else(|_| "<unprintable error>".to_owned()),
)),
}
}
}
2017-05-21 19:50:59 -04:00
impl<'lua> ToLua<'lua> for bool {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::Boolean(self))
}
}
impl<'lua> FromLua<'lua> for bool {
fn from_lua(v: LuaValue, _: &'lua Lua) -> LuaResult<Self> {
match v {
LuaValue::Nil => Ok(false),
LuaValue::Boolean(b) => Ok(b),
_ => Ok(true),
}
}
}
impl<'lua> ToLua<'lua> for LightUserData {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::LightUserData(self))
}
}
impl<'lua> FromLua<'lua> for LightUserData {
fn from_lua(v: LuaValue, _: &'lua Lua) -> LuaResult<Self> {
match v {
LuaValue::LightUserData(ud) => Ok(ud),
_ => Err(
LuaConversionError::FromLua(
"cannot convert lua value to lightuserdata".to_owned(),
).into(),
),
}
}
}
2017-05-21 19:50:59 -04:00
impl<'lua> ToLua<'lua> for String {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::String(lua.create_string(&self)?))
}
}
impl<'lua> FromLua<'lua> for String {
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
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 {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::String(lua.create_string(self)?))
}
}
macro_rules! lua_convert_int {
($x: ty) => {
impl<'lua> ToLua<'lua> for $x {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::Integer(self as LuaInteger))
}
}
impl<'lua> FromLua<'lua> for $x {
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
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 {
fn to_lua(self, _: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::Number(self as LuaNumber))
}
}
impl<'lua> FromLua<'lua> for $x {
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
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> {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::Table(lua.create_sequence_from(self)?))
2017-05-21 19:50:59 -04:00
}
}
impl<'lua, T: FromLua<'lua>> FromLua<'lua> for Vec<T> {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
if let LuaValue::Table(table) = value {
table.sequence_values().collect()
2017-05-21 19:50:59 -04:00
} else {
Err(
LuaConversionError::FromLua("cannot convert lua value to table for Vec".to_owned())
.into(),
)
2017-05-21 19:50:59 -04:00
}
}
}
impl<'lua, K: Eq + Hash + ToLua<'lua>, V: ToLua<'lua>> ToLua<'lua> for HashMap<K, V> {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::Table(lua.create_table_from(self)?))
2017-05-21 19:50:59 -04:00
}
}
impl<'lua, K: Eq + Hash + FromLua<'lua>, V: FromLua<'lua>> FromLua<'lua> for HashMap<K, V> {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
if let LuaValue::Table(table) = value {
table.pairs().collect()
2017-05-21 19:50:59 -04:00
} else {
Err(
LuaConversionError::FromLua(
"cannot convert lua value to table for HashMap".to_owned(),
).into(),
)
2017-05-21 19:50:59 -04:00
}
}
}
impl<'lua, K: Ord + ToLua<'lua>, V: ToLua<'lua>> ToLua<'lua> for BTreeMap<K, V> {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
Ok(LuaValue::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> {
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
if let LuaValue::Table(table) = value {
table.pairs().collect()
2017-05-21 19:50:59 -04:00
} else {
Err(
LuaConversionError::FromLua(
"cannot convert lua value to table for BTreeMap".to_owned(),
).into(),
)
2017-05-21 19:50:59 -04:00
}
}
}
impl<'lua, T: ToLua<'lua>> ToLua<'lua> for Option<T> {
fn to_lua(self, lua: &'lua Lua) -> LuaResult<LuaValue<'lua>> {
match self {
Some(val) => val.to_lua(lua),
None => Ok(LuaNil),
}
}
}
impl<'lua, T: FromLua<'lua>> FromLua<'lua> for Option<T> {
fn from_lua(value: LuaValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
match value {
LuaNil => Ok(None),
value => Ok(Some(T::from_lua(value, lua)?)),
}
}
}