use core::ops::{Deref, DerefMut};
use std::collections::{VecDeque, vec_deque};
use std::iter::FromIterator;
use crate::error::Error;
use crate::thread::Thread;
use crate::value::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, Value};
pub struct MultiValue<'lua> {
values: VecDeque<Value<'lua>>,
}
#[derive(Debug, Clone)]
pub struct Variadic<T>(Vec<T>);
impl<'lua> MultiValue<'lua> {
pub fn new() -> Self {
Self {
values: VecDeque::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
values: VecDeque::with_capacity(capacity),
}
}
pub fn from_vec(values: Vec<Value<'lua>>) -> Self {
Self {
values: values.into(),
}
}
pub fn into_vec(self) -> Vec<Value<'lua>> {
self.values.into()
}
pub fn len(&self) -> usize {
self.values.len()
}
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
pub fn push(&mut self, value: Value<'lua>) {
self.values.push_back(value);
}
pub fn pop_front(&mut self) -> Option<Value<'lua>> {
self.values.pop_front()
}
pub(crate) fn from_stack(
thread: &Thread<'lua>,
base_top: i32,
count: i32,
) -> Result<Self, Error> {
let mut values = Self::with_capacity(count.max(0) as usize);
for offset in 0..count {
values.push(Value::from_stack(thread, base_top + offset + 1)?);
}
Ok(values)
}
}
impl Default for MultiValue<'_> {
fn default() -> Self {
Self::new()
}
}
impl<'lua> From<Vec<Value<'lua>>> for MultiValue<'lua> {
fn from(value: Vec<Value<'lua>>) -> Self {
Self::from_vec(value)
}
}
impl<'lua> From<MultiValue<'lua>> for Vec<Value<'lua>> {
fn from(value: MultiValue<'lua>) -> Self {
value.into_vec()
}
}
impl<'lua> FromIterator<Value<'lua>> for MultiValue<'lua> {
fn from_iter<I: IntoIterator<Item = Value<'lua>>>(iter: I) -> Self {
Self {
values: iter.into_iter().collect(),
}
}
}
impl<'lua> IntoIterator for MultiValue<'lua> {
type Item = Value<'lua>;
type IntoIter = vec_deque::IntoIter<Value<'lua>>;
fn into_iter(self) -> Self::IntoIter {
self.values.into_iter()
}
}
impl<'a, 'lua> IntoIterator for &'a MultiValue<'lua> {
type Item = &'a Value<'lua>;
type IntoIter = vec_deque::Iter<'a, Value<'lua>>;
fn into_iter(self) -> Self::IntoIter {
self.values.iter()
}
}
impl<'lua> IntoLuaMulti<'lua> for MultiValue<'lua> {
fn into_lua_multi(self, _: crate::LuaRef<'lua>) -> Result<MultiValue<'lua>, Error> {
Ok(self)
}
}
impl<'lua, 'value> IntoLuaMulti<'lua> for &MultiValue<'value>
where
'value: 'lua,
{
fn into_lua_multi(self, _: crate::LuaRef<'lua>) -> Result<MultiValue<'lua>, Error> {
self.into_iter().map(Value::try_clone).collect()
}
unsafe fn push_into_stack_multi(self, thread: &Thread<'lua>) -> Result<usize, Error> {
thread.reserve_stack(self.len())?;
for value in self {
value.push_to(thread)?;
}
Ok(self.len())
}
}
impl<'lua> FromLuaMulti<'lua> for MultiValue<'lua> {
fn from_lua_multi(values: MultiValue<'lua>, _: crate::LuaRef<'lua>) -> Result<Self, Error> {
Ok(values)
}
unsafe fn from_stack_multi(
thread: &Thread<'lua>,
base_top: i32,
count: i32,
) -> Result<Self, Error> {
MultiValue::from_stack(thread, base_top, count)
}
}
impl<T> Variadic<T> {
pub const fn new() -> Self {
Self(Vec::new())
}
pub fn with_capacity(capacity: usize) -> Self {
Self(Vec::with_capacity(capacity))
}
pub fn from_vec(values: Vec<T>) -> Self {
Self(values)
}
pub fn into_vec(self) -> Vec<T> {
self.0
}
}
impl<T> Default for Variadic<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Deref for Variadic<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Variadic<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> From<Vec<T>> for Variadic<T> {
fn from(values: Vec<T>) -> Self {
Self::from_vec(values)
}
}
impl<T> From<Variadic<T>> for Vec<T> {
fn from(values: Variadic<T>) -> Self {
values.into_vec()
}
}
impl<T> FromIterator<T> for Variadic<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self(iter.into_iter().collect())
}
}
impl<T> IntoIterator for Variadic<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a, T> IntoIterator for &'a Variadic<T> {
type Item = &'a T;
type IntoIter = std::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<'a, T> IntoIterator for &'a mut Variadic<T> {
type Item = &'a mut T;
type IntoIter = std::slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
impl<'lua, T> IntoLuaMulti<'lua> for Variadic<T>
where
T: IntoLua<'lua>,
{
fn into_lua_multi(self, thread: crate::LuaRef<'lua>) -> Result<MultiValue<'lua>, Error> {
self.into_iter()
.map(|value| value.into_lua(thread))
.collect()
}
unsafe fn push_into_stack_multi(self, thread: &Thread<'lua>) -> Result<usize, Error> {
let count = self.len();
thread.reserve_stack(count)?;
for value in self {
unsafe {
value.push_into_stack(thread)?;
}
}
Ok(count)
}
}
impl<'lua, T> FromLuaMulti<'lua> for Variadic<T>
where
T: FromLua<'lua>,
{
fn from_lua_multi(
values: MultiValue<'lua>,
thread: crate::LuaRef<'lua>,
) -> Result<Self, Error> {
values
.into_iter()
.map(|value| T::from_lua(value, thread))
.collect()
}
unsafe fn from_stack_multi(
thread: &Thread<'lua>,
base_top: i32,
count: i32,
) -> Result<Self, Error> {
let count = count.max(0);
let mut values = Self::with_capacity(count as usize);
for offset in 0..count {
values
.0
.push(unsafe { T::from_stack(thread, base_top + offset + 1)? });
}
Ok(values)
}
}