1use crate::*;
2use std::fmt;
3use std::marker::PhantomData;
4
5#[derive(Clone)]
6pub struct Array {
7 pub(crate) mv8: MiniV8,
8 pub(crate) handle: v8::Global<v8::Array>,
9}
10
11impl Array {
12 pub fn into_object(self) -> Object {
14 self.mv8.clone().scope(|scope| {
15 let object: v8::Local<v8::Object> = v8::Local::new(scope, self.handle.clone()).into();
16 Object {
17 mv8: self.mv8,
18 handle: v8::Global::new(scope, object),
19 }
20 })
21 }
22
23 pub fn get<V: FromValue>(&self, index: u32) -> Result<V> {
28 self.mv8.try_catch(|scope| {
29 let array = v8::Local::new(scope, self.handle.clone());
30 let result = array.get_index(scope, index);
31 self.mv8.exception(scope)?;
32 Ok(Value::from_v8_value(&self.mv8, scope, result.unwrap()))
33 }).and_then(|v| v.into(&self.mv8))
34 }
35
36 pub fn set<V: ToValue>(&self, index: u32, value: V) -> Result<()> {
40 let value = value.to_value(&self.mv8)?;
41 self.mv8.try_catch(|scope| {
42 let array = v8::Local::new(scope, self.handle.clone());
43 let value = value.to_v8_value(scope);
44 array.set_index(scope, index, value);
45 self.mv8.exception(scope)
46 })
47 }
48
49 pub fn len(&self) -> u32 {
51 self.mv8.scope(|scope| v8::Local::new(scope, self.handle.clone()).length())
52 }
53
54 pub fn push<V: ToValue>(&self, value: V) -> Result<()> {
57 self.set(self.len(), value)
58 }
59
60 pub fn elements<V: FromValue>(self) -> Elements<V> {
62 Elements {
63 array: self,
64 index: 0,
65 len: None,
66 _phantom: PhantomData,
67 }
68 }
69}
70
71impl fmt::Debug for Array {
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73 let len = self.len();
74 write!(f, "[")?;
75 for i in 0..len {
76 match self.get::<Value>(i) {
77 Ok(v) => write!(f, "{:?}", v)?,
78 Err(_) => write!(f, "?")?,
79 };
80 if i + 1 < len {
81 write!(f, ", ")?;
82 }
83 }
84 write!(f, "]")
85 }
86}
87
88pub struct Elements<V> {
89 array: Array,
90 index: u32,
91 len: Option<u32>,
92 _phantom: PhantomData<V>,
93}
94
95impl<V: FromValue> Iterator for Elements<V> {
96 type Item = Result<V>;
97
98 fn next(&mut self) -> Option<Self::Item> {
99 if self.len.is_none() {
100 self.len = Some(self.array.len());
101 }
102
103 if self.index >= self.len.unwrap() {
104 return None;
105 }
106
107 let result = self.array.get(self.index);
108 self.index += 1;
109 Some(result)
110 }
111}