use std::ffi::c_uint;
use crate::codec::{CodecError, Decoder, Encoder};
use crate::types::{AnyTerm, Env, List, RawTerm, Term};
impl<'id, T: Encoder<'id>> Encoder<'id> for [T] {
fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
let mut raw: Vec<RawTerm> = Vec::with_capacity(self.len());
for item in self {
raw.push(item.encode(env)?.raw_term());
}
let term =
unsafe { enif_ffi::make_list_from_array(env.raw_env(), raw.as_ptr(), raw.len() as c_uint) };
Ok(AnyTerm::wrap(term, env))
}
}
impl<'id, T: Encoder<'id>> Encoder<'id> for Vec<T> {
fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
self.as_slice().encode(env)
}
}
impl<'id, T: Decoder<'id>> Decoder<'id> for Vec<T> {
fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
let list = List::decode(term, env)?;
let mut out = Vec::new();
let mut iter = list.iter(env);
for head in &mut iter {
out.push(T::decode(head, env)?);
}
let tail = iter.tail().expect("ListIterator yields its terminal once exhausted");
if unsafe { enif_ffi::is_empty_list(env.raw_env(), tail.raw_term()) } != 0 {
Ok(out)
} else {
Err(CodecError::WrongType)
}
}
}