use std::iter::{self, FromIterator};
use std::{slice, str, vec};
use crate::context::Context;
use crate::error::{Error, Result};
use crate::function::Function;
use crate::string::String;
use crate::table::Table;
use crate::thread::Thread;
#[cfg(any(rlua_lua53, rlua_lua54))]
use crate::types::Integer;
use crate::types::{LightUserData, Number};
use crate::userdata::AnyUserData;
#[derive(Debug, Clone)]
pub enum Value<'lua> {
Nil,
Boolean(bool),
LightUserData(LightUserData),
#[cfg(any(rlua_lua53, rlua_lua54))]
Integer(Integer),
Number(Number),
String(String<'lua>),
Table(Table<'lua>),
Function(Function<'lua>),
Thread(Thread<'lua>),
UserData(AnyUserData<'lua>),
Error(Error),
}
pub use self::Value::Nil;
impl<'lua> Value<'lua> {
pub fn type_name(&self) -> &'static str {
match *self {
Value::Nil => "nil",
Value::Boolean(_) => "boolean",
Value::LightUserData(_) => "lightuserdata",
#[cfg(any(rlua_lua53, rlua_lua54))]
Value::Integer(_) => "integer",
Value::Number(_) => "number",
Value::String(_) => "string",
Value::Table(_) => "table",
Value::Function(_) => "function",
Value::Thread(_) => "thread",
Value::UserData(_) => "userdata",
Value::Error(_) => "error",
}
}
}
pub trait ToLua<'lua> {
fn to_lua(self, lua: Context<'lua>) -> Result<Value<'lua>>;
}
pub trait FromLua<'lua>: Sized {
fn from_lua(lua_value: Value<'lua>, lua: Context<'lua>) -> Result<Self>;
}
#[derive(Debug, Clone)]
pub struct MultiValue<'lua>(Vec<Value<'lua>>);
impl<'lua> MultiValue<'lua> {
pub fn new() -> MultiValue<'lua> {
MultiValue(Vec::new())
}
}
impl<'lua> Default for MultiValue<'lua> {
fn default() -> MultiValue<'lua> {
MultiValue::new()
}
}
impl<'lua> FromIterator<Value<'lua>> for MultiValue<'lua> {
fn from_iter<I: IntoIterator<Item = Value<'lua>>>(iter: I) -> Self {
MultiValue::from_vec(Vec::from_iter(iter))
}
}
impl<'lua> IntoIterator for MultiValue<'lua> {
type Item = Value<'lua>;
type IntoIter = iter::Rev<vec::IntoIter<Value<'lua>>>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter().rev()
}
}
impl<'a, 'lua> IntoIterator for &'a MultiValue<'lua> {
type Item = &'a Value<'lua>;
type IntoIter = iter::Rev<slice::Iter<'a, Value<'lua>>>;
fn into_iter(self) -> Self::IntoIter {
(&self.0).into_iter().rev()
}
}
impl<'lua> MultiValue<'lua> {
pub fn from_vec(mut v: Vec<Value<'lua>>) -> MultiValue<'lua> {
v.reverse();
MultiValue(v)
}
pub fn into_vec(self) -> Vec<Value<'lua>> {
let mut v = self.0;
v.reverse();
v
}
pub(crate) fn reserve(&mut self, size: usize) {
self.0.reserve(size);
}
pub(crate) fn push_front(&mut self, value: Value<'lua>) {
self.0.push(value);
}
pub(crate) fn pop_front(&mut self) -> Option<Value<'lua>> {
self.0.pop()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.len() == 0
}
pub fn iter(&self) -> iter::Rev<slice::Iter<Value<'lua>>> {
self.0.iter().rev()
}
}
pub trait ToLuaMulti<'lua> {
fn to_lua_multi(self, lua: Context<'lua>) -> Result<MultiValue<'lua>>;
}
pub trait FromLuaMulti<'lua>: Sized {
fn from_lua_multi(values: MultiValue<'lua>, lua: Context<'lua>) -> Result<Self>;
}