quickjs_rusty/value/
array.rsuse std::ops::Deref;
use libquickjs_ng_sys as q;
use crate::{ExecutionError, ValueError};
use super::OwnedJsValue;
pub struct OwnedJsArray {
value: OwnedJsValue,
}
impl OwnedJsArray {
pub fn try_from_value(value: OwnedJsValue) -> Result<Self, ValueError> {
if !value.is_array() {
Err(ValueError::Internal("Expected an array".into()))
} else {
Ok(Self { value })
}
}
pub fn length(&self) -> u64 {
let mut next_index: i64 = 0;
unsafe {
q::JS_GetLength(
self.value.context(),
self.value.value,
&mut next_index as *mut _,
);
}
next_index as u64
}
pub fn get_index(&self, index: u32) -> Result<Option<OwnedJsValue>, ExecutionError> {
let value_raw =
unsafe { q::JS_GetPropertyUint32(self.value.context(), self.value.value, index) };
let tag = unsafe { q::JS_Ext_ValueGetTag(value_raw) };
if tag == q::JS_TAG_EXCEPTION {
return Err(ExecutionError::Internal("Could not build array".into()));
} else if tag == q::JS_TAG_UNDEFINED {
return Ok(None);
}
Ok(Some(OwnedJsValue::new(self.value.context(), value_raw)))
}
pub fn set_index(&self, index: u32, value: OwnedJsValue) -> Result<(), ExecutionError> {
unsafe {
let ret =
q::JS_SetPropertyUint32(self.value.context(), self.value.value, index, value.value);
if ret < 0 {
Err(ExecutionError::Internal("Could not set property".into()))
} else {
std::mem::forget(value);
Ok(())
}
}
}
pub fn push(&self, value: OwnedJsValue) -> Result<(), ExecutionError> {
unsafe {
let mut next_index: i64 = 0;
q::JS_GetLength(
self.value.context(),
self.value.value,
&mut next_index as *mut _,
);
let ret = q::JS_SetPropertyInt64(
self.value.context(),
self.value.value,
next_index,
value.value,
);
if ret < 0 {
Err(ExecutionError::Internal(
"Could not set property".to_string(),
))
} else {
std::mem::forget(value);
Ok(())
}
}
}
pub fn raw_elements(&self) -> Vec<q::JSValue> {
let mut ret = vec![];
let length = self.length() as u32;
for i in 0..length {
let value_raw =
unsafe { q::JS_GetPropertyUint32(self.value.context(), self.value.value, i) };
ret.push(value_raw);
}
ret
}
}
impl Deref for OwnedJsArray {
type Target = OwnedJsValue;
fn deref(&self) -> &Self::Target {
&self.value
}
}