use crate::{ffi, IntoDart};
use core::slice;
use ffi::{DartCObject, DartCObjectType, DartCObjectValue, DartNativeArray};
use std::mem::ManuallyDrop;
#[derive(Debug, Clone)]
pub struct DartArray {
inner: Box<[*mut DartCObject]>,
}
impl<T: IntoDart> From<Vec<T>> for DartArray {
fn from(vec: Vec<T>) -> Self {
let vec: Vec<_> = vec.
into_iter()
.map(IntoDart::into_dart)
.map(Box::new)
.map(Box::into_raw)
.collect();
let inner = vec.into_boxed_slice();
Self { inner }
}
}
impl IntoDart for DartArray {
fn into_dart(self) -> ffi::DartCObject {
let mut s = ManuallyDrop::new(self);
let (data, len) = (s.inner.as_mut_ptr(), s.inner.len());
let array = DartNativeArray {
length: len as isize,
values: data,
};
DartCObject {
ty: DartCObjectType::DartArray,
value: DartCObjectValue { as_array: array },
}
}
}
impl From<DartNativeArray> for DartArray {
fn from(arr: DartNativeArray) -> Self {
let inner = unsafe {
let slice =
slice::from_raw_parts_mut(arr.values, arr.length as usize);
Box::from_raw(slice)
};
Self { inner }
}
}
impl Drop for DartArray {
fn drop(&mut self) {
for v in self.inner.iter() {
unsafe {
Box::from_raw(*v);
}
}
}
}