quickjs_rusty/value/
array.rs1use std::ops::Deref;
2
3use libquickjs_ng_sys as q;
4
5use crate::{ExecutionError, ValueError};
6
7use super::OwnedJsValue;
8
9pub struct OwnedJsArray {
10 value: OwnedJsValue,
11}
12
13impl OwnedJsArray {
14 pub fn try_from_value(value: OwnedJsValue) -> Result<Self, ValueError> {
15 if !value.is_array() {
16 Err(ValueError::Internal("Expected an array".into()))
17 } else {
18 Ok(Self { value })
19 }
20 }
21
22 pub fn length(&self) -> u64 {
23 let mut next_index: i64 = 0;
24 unsafe {
25 q::JS_GetLength(
26 self.value.context(),
27 self.value.value,
28 &mut next_index as *mut _,
29 );
30 }
31
32 next_index as u64
33 }
34
35 pub fn get_index(&self, index: u32) -> Result<Option<OwnedJsValue>, ExecutionError> {
36 let value_raw =
37 unsafe { q::JS_GetPropertyUint32(self.value.context(), self.value.value, index) };
38 let tag = unsafe { q::JS_Ext_ValueGetTag(value_raw) };
39 if tag == q::JS_TAG_EXCEPTION {
40 return Err(ExecutionError::Internal("Could not build array".into()));
41 } else if tag == q::JS_TAG_UNDEFINED {
42 return Ok(None);
43 }
44
45 Ok(Some(OwnedJsValue::new(self.value.context(), value_raw)))
46 }
47
48 pub fn set_index(&self, index: u32, value: OwnedJsValue) -> Result<(), ExecutionError> {
49 unsafe {
50 let ret =
56 q::JS_SetPropertyUint32(self.value.context(), self.value.value, index, value.value);
57
58 if ret < 0 {
59 Err(ExecutionError::Internal("Could not set property".into()))
60 } else {
61 std::mem::forget(value);
63 Ok(())
64 }
65 }
66 }
67
68 pub fn push(&self, value: OwnedJsValue) -> Result<(), ExecutionError> {
69 unsafe {
70 let mut next_index: i64 = 0;
71 q::JS_GetLength(
72 self.value.context(),
73 self.value.value,
74 &mut next_index as *mut _,
75 );
76 let ret = q::JS_SetPropertyInt64(
82 self.value.context(),
83 self.value.value,
84 next_index,
85 value.value,
86 );
87
88 if ret < 0 {
89 Err(ExecutionError::Internal(
90 "Could not set property".to_string(),
91 ))
92 } else {
93 std::mem::forget(value);
95 Ok(())
96 }
97 }
98 }
99
100 pub fn raw_elements(&self) -> Vec<q::JSValue> {
101 let mut ret = vec![];
102 let length = self.length() as u32;
103 for i in 0..length {
104 let value_raw =
105 unsafe { q::JS_GetPropertyUint32(self.value.context(), self.value.value, i) };
106 ret.push(value_raw);
107 }
108 ret
109 }
110}
111
112impl Deref for OwnedJsArray {
113 type Target = OwnedJsValue;
114
115 fn deref(&self) -> &Self::Target {
116 &self.value
117 }
118}