use crate::Result;
use crate::arena::DataValue;
use crate::operators::eager::Cx;
#[inline]
fn pairs_of<'a>(
cx: &mut Cx<'_, 'a>,
object: Option<&'a [(&'a str, DataValue<'a>)]>,
) -> Result<Option<&'a [(&'a str, DataValue<'a>)]>> {
match object {
None | Some([]) => Ok(None),
Some(pairs) => {
cx.charge(pairs.len() as u64)?;
Ok(Some(pairs))
}
}
}
#[inline]
pub(crate) fn keys<'a>(
cx: &mut Cx<'_, 'a>,
object: Option<&'a [(&'a str, DataValue<'a>)]>,
) -> Result<&'a DataValue<'a>> {
let Some(pairs) = pairs_of(cx, object)? else {
return Ok(crate::arena::singletons::singleton_empty_array());
};
let slice = cx
.arena
.alloc_slice_fill_iter(pairs.iter().map(|(k, _)| DataValue::String(k)));
Ok(cx.alloc(DataValue::Array(slice)))
}
#[inline]
pub(crate) fn values<'a>(
cx: &mut Cx<'_, 'a>,
object: Option<&'a [(&'a str, DataValue<'a>)]>,
) -> Result<&'a DataValue<'a>> {
let Some(pairs) = pairs_of(cx, object)? else {
return Ok(crate::arena::singletons::singleton_empty_array());
};
let slice = cx
.arena
.alloc_slice_fill_iter(pairs.iter().map(|(_, v)| *v));
Ok(cx.alloc(DataValue::Array(slice)))
}
#[inline]
pub(crate) fn entries<'a>(
cx: &mut Cx<'_, 'a>,
object: Option<&'a [(&'a str, DataValue<'a>)]>,
) -> Result<&'a DataValue<'a>> {
let Some(pairs) = pairs_of(cx, object)? else {
return Ok(crate::arena::singletons::singleton_empty_array());
};
let arena = cx.arena;
let slice = arena.alloc_slice_fill_iter(pairs.iter().map(|(k, v)| {
let row = arena.alloc([("key", DataValue::String(k)), ("value", *v)]);
DataValue::Object(&row[..])
}));
Ok(cx.alloc(DataValue::Array(slice)))
}