use core::cmp::Ordering;
use core::iter;
use crate as rune;
use crate::alloc;
use crate::alloc::fmt::TryWrite;
use crate::alloc::prelude::*;
use crate::runtime::{
EnvProtocolCaller, Formatter, Iterator, Protocol, ProtocolCaller, RawAnyGuard, Ref, Value, Vec,
VmErrorKind, VmResult,
};
use crate::{Any, ContextError, Module};
#[rune::module(::std::collections::vec_deque)]
pub fn module() -> Result<Module, ContextError> {
let mut m = Module::from_meta(self::module_meta)?;
m.ty::<VecDeque>()?;
m.function_meta(VecDeque::new)?;
m.function_meta(VecDeque::with_capacity__meta)?;
m.function_meta(from)?;
m.function_meta(VecDeque::extend)?;
m.function_meta(VecDeque::insert)?;
m.function_meta(VecDeque::iter__meta)?;
m.function_meta(VecDeque::into_iter__meta)?;
m.function_meta(VecDeque::from_iter__meta)?;
m.function_meta(VecDeque::reserve)?;
m.function_meta(VecDeque::len)?;
m.function_meta(VecDeque::capacity)?;
m.function_meta(VecDeque::front)?;
m.function_meta(VecDeque::back)?;
m.function_meta(VecDeque::push_back__meta)?;
m.function_meta(VecDeque::push_front)?;
m.function_meta(VecDeque::pop_front)?;
m.function_meta(VecDeque::pop_back)?;
m.function_meta(VecDeque::remove)?;
m.function_meta(VecDeque::rotate_left)?;
m.function_meta(VecDeque::rotate_right)?;
m.associated_function(&Protocol::INDEX_GET, VecDeque::get)?;
m.associated_function(&Protocol::INDEX_SET, VecDeque::set)?;
m.function_meta(VecDeque::debug_fmt)?;
m.function_meta(VecDeque::partial_eq__meta)?;
m.implement_trait::<VecDeque>(rune::item!(::std::cmp::PartialEq))?;
m.function_meta(VecDeque::eq__meta)?;
m.implement_trait::<VecDeque>(rune::item!(::std::cmp::Eq))?;
m.function_meta(VecDeque::partial_cmp__meta)?;
m.implement_trait::<VecDeque>(rune::item!(::std::cmp::PartialOrd))?;
m.function_meta(VecDeque::cmp__meta)?;
m.implement_trait::<VecDeque>(rune::item!(::std::cmp::Ord))?;
m.ty::<Iter>()?;
m.function_meta(Iter::next__meta)?;
m.function_meta(Iter::size_hint__meta)?;
m.implement_trait::<Iter>(rune::item!(::std::iter::Iterator))?;
m.function_meta(Iter::next_back__meta)?;
m.implement_trait::<Iter>(rune::item!(::std::iter::DoubleEndedIterator))?;
m.function_meta(Iter::len__meta)?;
m.implement_trait::<Iter>(rune::item!(::std::iter::ExactSizeIterator))?;
Ok(m)
}
#[derive(Any, Default)]
#[rune(module = crate, item = ::std::collections::vec_deque)]
pub(crate) struct VecDeque {
inner: alloc::VecDeque<Value>,
}
impl VecDeque {
#[rune::function(path = Self::new)]
fn new() -> VecDeque {
Self {
inner: alloc::VecDeque::new(),
}
}
#[rune::function(keep, path = Self::with_capacity)]
pub(crate) fn with_capacity(count: usize) -> VmResult<VecDeque> {
VmResult::Ok(Self {
inner: vm_try!(alloc::VecDeque::try_with_capacity(count)),
})
}
#[rune::function]
pub fn extend(&mut self, value: Value) -> VmResult<()> {
let mut it = vm_try!(value.into_iter());
while let Some(value) = vm_try!(it.next()) {
vm_try!(self.inner.try_push_back(value));
}
VmResult::Ok(())
}
#[rune::function]
fn front(&mut self) -> Option<Value> {
self.inner.front().cloned()
}
#[rune::function]
pub fn back(&self) -> Option<Value> {
self.inner.back().cloned()
}
#[rune::function(keep)]
pub(crate) fn push_back(&mut self, value: Value) -> VmResult<()> {
vm_try!(self.inner.try_push_back(value));
VmResult::Ok(())
}
#[rune::function]
fn push_front(&mut self, value: Value) -> VmResult<()> {
vm_try!(self.inner.try_push_front(value));
VmResult::Ok(())
}
#[rune::function]
fn pop_front(&mut self) -> Option<Value> {
self.inner.pop_front()
}
#[rune::function]
fn pop_back(&mut self) -> Option<Value> {
self.inner.pop_back()
}
#[rune::function]
fn reserve(&mut self, index: usize) -> VmResult<()> {
vm_try!(self.inner.try_reserve(index));
VmResult::Ok(())
}
#[rune::function]
fn len(&self) -> usize {
self.inner.len()
}
#[rune::function]
fn capacity(&mut self) -> usize {
self.inner.capacity()
}
#[rune::function]
fn insert(&mut self, index: usize, value: Value) -> VmResult<()> {
if index > self.inner.len() {
return VmResult::err(VmErrorKind::OutOfRange {
index: index.into(),
length: self.inner.len().into(),
});
}
vm_try!(self.inner.try_insert(index, value));
VmResult::Ok(())
}
#[rune::function]
fn remove(&mut self, index: usize) -> Option<Value> {
self.inner.remove(index)
}
#[rune::function]
fn rotate_left(&mut self, mid: usize) -> VmResult<()> {
if mid > self.inner.len() {
return VmResult::err(VmErrorKind::OutOfRange {
index: mid.into(),
length: self.inner.len().into(),
});
}
self.inner.rotate_left(mid);
VmResult::Ok(())
}
#[rune::function]
fn rotate_right(&mut self, mid: usize) -> VmResult<()> {
if mid > self.inner.len() {
return VmResult::err(VmErrorKind::OutOfRange {
index: mid.into(),
length: self.inner.len().into(),
});
}
self.inner.rotate_right(mid);
VmResult::Ok(())
}
#[inline]
#[rune::function(keep, instance, path = Self::iter)]
fn iter(this: Ref<Self>) -> Iter {
let iter = unsafe { this.inner.raw_iter() };
let (_, guard) = Ref::into_raw(this);
Iter { iter, guard }
}
#[rune::function(keep, instance, protocol = INTO_ITER, path = Self)]
fn into_iter(this: Ref<Self>) -> Iter {
Self::iter(this)
}
#[rune::function(keep, path = Self::from_iter)]
fn from_iter(mut it: Iterator) -> VmResult<Self> {
let (lo, _) = vm_try!(it.size_hint());
let mut inner = vm_try!(alloc::VecDeque::try_with_capacity(lo));
while let Some(value) = vm_try!(it.next()) {
vm_try!(inner.try_push_back(value));
}
VmResult::Ok(Self { inner })
}
fn get(&self, index: usize) -> VmResult<Value> {
let Some(v) = self.inner.get(index) else {
return VmResult::err(VmErrorKind::OutOfRange {
index: index.into(),
length: self.inner.len().into(),
});
};
VmResult::Ok(v.clone())
}
fn set(&mut self, index: usize, value: Value) -> VmResult<()> {
let Some(v) = self.inner.get_mut(index) else {
return VmResult::err(VmErrorKind::OutOfRange {
index: index.into(),
length: self.inner.len().into(),
});
};
*v = value;
VmResult::Ok(())
}
#[rune::function(protocol = DEBUG_FMT)]
fn debug_fmt(&self, f: &mut Formatter) -> VmResult<()> {
self.debug_fmt_with(f, &mut EnvProtocolCaller)
}
#[inline]
fn debug_fmt_with(&self, f: &mut Formatter, caller: &mut dyn ProtocolCaller) -> VmResult<()> {
let mut it = self.inner.iter().peekable();
vm_try!(vm_write!(f, "["));
while let Some(value) = it.next() {
vm_try!(value.debug_fmt_with(f, caller));
if it.peek().is_some() {
vm_try!(vm_write!(f, ", "));
}
}
vm_try!(vm_write!(f, "]"));
VmResult::Ok(())
}
#[rune::function(keep, protocol = PARTIAL_EQ)]
fn partial_eq(&self, b: Value) -> VmResult<bool> {
self.partial_eq_with(b, &mut EnvProtocolCaller)
}
fn partial_eq_with(&self, b: Value, caller: &mut dyn ProtocolCaller) -> VmResult<bool> {
let mut b = vm_try!(b.into_iter_with(caller));
for a in &self.inner {
let Some(b) = vm_try!(b.next()) else {
return VmResult::Ok(false);
};
if !vm_try!(Value::partial_eq_with(a, &b, caller)) {
return VmResult::Ok(false);
}
}
if vm_try!(b.next()).is_some() {
return VmResult::Ok(false);
}
VmResult::Ok(true)
}
#[rune::function(keep, protocol = EQ)]
fn eq(&self, b: &VecDeque) -> VmResult<bool> {
self.eq_with(b, &mut EnvProtocolCaller)
}
fn eq_with(&self, b: &VecDeque, caller: &mut dyn ProtocolCaller) -> VmResult<bool> {
let mut b = b.inner.iter();
for a in &self.inner {
let Some(b) = b.next() else {
return VmResult::Ok(false);
};
if !vm_try!(Value::eq_with(a, b, caller)) {
return VmResult::Ok(false);
}
}
if b.next().is_some() {
return VmResult::Ok(false);
}
VmResult::Ok(true)
}
#[rune::function(keep, protocol = PARTIAL_CMP)]
fn partial_cmp(&self, b: &VecDeque) -> VmResult<Option<Ordering>> {
self.partial_cmp_with(b, &mut EnvProtocolCaller)
}
fn partial_cmp_with(
&self,
b: &VecDeque,
caller: &mut dyn ProtocolCaller,
) -> VmResult<Option<Ordering>> {
let mut b = b.inner.iter();
for a in self.inner.iter() {
let Some(b) = b.next() else {
return VmResult::Ok(Some(Ordering::Greater));
};
match vm_try!(Value::partial_cmp_with(a, b, caller)) {
Some(Ordering::Equal) => (),
other => return VmResult::Ok(other),
}
}
if b.next().is_some() {
return VmResult::Ok(Some(Ordering::Less));
};
VmResult::Ok(Some(Ordering::Equal))
}
#[rune::function(keep, protocol = CMP)]
fn cmp(&self, b: &VecDeque) -> VmResult<Ordering> {
self.cmp_with(b, &mut EnvProtocolCaller)
}
fn cmp_with(&self, other: &VecDeque, caller: &mut dyn ProtocolCaller) -> VmResult<Ordering> {
let mut b = other.inner.iter();
for a in self.inner.iter() {
let Some(b) = b.next() else {
return VmResult::Ok(Ordering::Greater);
};
match vm_try!(Value::cmp_with(a, b, caller)) {
Ordering::Equal => (),
other => return VmResult::Ok(other),
}
}
if b.next().is_some() {
return VmResult::Ok(Ordering::Less);
};
VmResult::Ok(Ordering::Equal)
}
}
impl From<Vec> for VecDeque {
fn from(value: Vec) -> Self {
Self {
inner: alloc::VecDeque::from(value.into_inner()),
}
}
}
impl TryClone for VecDeque {
#[inline]
fn try_clone(&self) -> alloc::Result<Self> {
Ok(Self {
inner: self.inner.try_clone()?,
})
}
#[inline]
fn try_clone_from(&mut self, source: &Self) -> alloc::Result<()> {
self.inner.try_clone_from(&source.inner)
}
}
#[rune::function(free, path = VecDeque::from::<Vec>)]
fn from(vec: Vec) -> VmResult<VecDeque> {
VmResult::Ok(VecDeque::from(vec))
}
#[derive(Any)]
#[rune(item = ::std::collections::vec_deque)]
pub(crate) struct Iter {
iter: alloc::vec_deque::RawIter<Value>,
#[allow(unused)]
guard: RawAnyGuard,
}
impl Iter {
#[rune::function(keep, protocol = NEXT)]
fn next(&mut self) -> Option<Value> {
unsafe { Some((*self.iter.next()?).clone()) }
}
#[rune::function(keep, protocol = SIZE_HINT)]
fn size_hint(self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[rune::function(keep, protocol = LEN)]
fn len(self) -> usize {
self.iter.len()
}
#[rune::function(keep, protocol = NEXT_BACK)]
fn next_back(&mut self) -> Option<Value> {
unsafe { Some((*self.iter.next_back()?).clone()) }
}
}
impl iter::Iterator for Iter {
type Item = Value;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
Iter::next(self)
}
}
impl iter::DoubleEndedIterator for Iter {
fn next_back(&mut self) -> Option<Self::Item> {
Iter::next_back(self)
}
}