use std::convert::From;
use std::default::Default;
use std::iter::{FromIterator, IntoIterator, Iterator};
use binding::array;
use types::{Value, ValueType};
use {AnyObject, RString, Object, VerifiedObject};
#[derive(Debug, PartialEq)]
pub struct Array {
value: Value,
}
impl Array {
pub fn new() -> Self {
Self::from(array::new())
}
pub fn with_capacity(capacity: usize) -> Self {
Self::from(array::with_capacity(capacity))
}
pub fn length(&self) -> usize {
array::len(self.value()) as usize
}
pub fn at(&self, index: i64) -> AnyObject {
let result = array::entry(self.value(), index);
AnyObject::from(result)
}
pub fn join(&self, separator: RString) -> RString {
let result = array::join(self.value(), separator.value());
RString::from(result)
}
pub fn push<T: Object>(&mut self, item: T) -> Self {
let result = array::push(self.value(), item.value());
Array::from(result)
}
pub fn store<T: Object>(&mut self, index: i64, item: T) -> AnyObject {
let result = array::store(self.value(), index, item.value());
AnyObject::from(result)
}
pub fn pop(&mut self) -> AnyObject {
let result = array::pop(self.value());
AnyObject::from(result)
}
pub fn unshift<T: Object>(&mut self, item: T) -> Array {
let result = array::unshift(self.value(), item.value());
Array::from(result)
}
pub fn shift(&mut self) -> AnyObject {
let result = array::shift(self.value());
AnyObject::from(result)
}
pub fn dup(&self) -> Array {
let result = array::dup(self.value());
Array::from(result)
}
pub fn to_s(&self) -> RString {
let result = array::to_s(self.value());
RString::from(result)
}
pub fn reverse(&self) -> Array {
self.dup().reverse_bang()
}
pub fn reverse_bang(&mut self) -> Array {
let result = array::reverse_bang(self.value());
Array::from(result)
}
pub fn concat(&mut self, other: &Array) -> Array {
let result = array::concat(self.value(), other.value());
Array::from(result)
}
pub fn sort(&self) -> Array {
let result = array::sort(self.value());
Array::from(result)
}
pub fn sort_bang(&mut self) -> Array {
let result = array::sort_bang(self.value());
Array::from(result)
}
}
impl Default for Array {
fn default() -> Self {
Array::new()
}
}
impl From<Value> for Array {
fn from(value: Value) -> Self {
Array { value: value }
}
}
impl Object for Array {
#[inline]
fn value(&self) -> Value {
self.value
}
}
impl VerifiedObject for Array {
fn is_correct_type<T: Object>(object: &T) -> bool {
object.value().ty() == ValueType::Array
}
fn error_message() -> &'static str {
"Error converting to Boolean"
}
}
pub struct ArrayIterator {
array: Array,
current_index: i64,
}
impl ArrayIterator {
fn new(array: Array) -> ArrayIterator {
ArrayIterator {
array: array,
current_index: 0,
}
}
}
impl Iterator for ArrayIterator {
type Item = AnyObject;
fn next(&mut self) -> Option<AnyObject> {
let item = if (self.current_index as usize) < self.len() {
Some(self.array.at(self.current_index))
} else {
None
};
self.current_index += 1;
item
}
fn size_hint(&self) -> (usize, Option<usize>) {
let total = self.len() as usize;
(total, Some(total))
}
}
impl ExactSizeIterator for ArrayIterator {
fn len(&self) -> usize {
self.array.length() as usize
}
}
impl IntoIterator for Array {
type Item = AnyObject;
type IntoIter = ArrayIterator;
fn into_iter(self) -> Self::IntoIter {
ArrayIterator::new(self)
}
}
impl FromIterator<AnyObject> for Array {
fn from_iter<I: IntoIterator<Item = AnyObject>>(iter: I) -> Self {
let mut array = Array::new();
for i in iter {
array.push(i);
}
array
}
}