Skip to main content

sim_codec/implementation/
list_encode.rs

1//! Shared value-to-`Expr` encode machinery for lists and nested data.
2//!
3//! Forces list values into bounded vectors and walks values (lists, tables,
4//! atoms) into the kernel `Expr` graph for encoding.
5
6use sim_kernel::{Cx, Error, Expr, Result, Value, WriteCx, force_list_to_vec};
7
8/// Force a list value into a bounded Vec for v1 encoding.
9pub fn force_list_for_encode(cx: &mut Cx, list: &Value) -> Result<Vec<Value>> {
10    let lv = list
11        .object()
12        .as_list()
13        .ok_or_else(|| Error::Eval("encode: value is not a list".to_owned()))?;
14    force_list_to_vec(cx, lv, "encode")
15}
16
17fn force_table_for_encode(cx: &mut Cx, table: &Value) -> Result<Expr> {
18    let table = table
19        .object()
20        .as_table_impl()
21        .ok_or_else(|| Error::Eval("encode: value is not a table".to_owned()))?;
22    let expr = table.as_table_expr(cx)?;
23    if matches!(expr, Expr::Map(_)) {
24        Ok(expr)
25    } else {
26        Err(Error::Eval(
27            "encode: table backend did not materialize to Expr::Map".to_owned(),
28        ))
29    }
30}
31
32/// Walk a runtime `Value` into a kernel `Expr` ready for encoding.
33///
34/// Lists and tables are forced and recursed into; every other value is lowered
35/// through its own [`as_expr`](sim_kernel::ObjectCompat::as_expr). This is the
36/// value-side entry point that [`encode_value_with_codec`](crate::encode_value_with_codec)
37/// runs before handing the `Expr` to a codec.
38pub fn encode_value_expr(cx: &mut WriteCx<'_>, value: &Value) -> Result<Expr> {
39    if value.object().as_list().is_some() {
40        return Ok(Expr::List(
41            force_list_for_encode(cx.cx, value)?
42                .into_iter()
43                .map(|item| encode_value_expr(cx, &item))
44                .collect::<Result<Vec<_>>>()?,
45        ));
46    }
47
48    if value.object().as_table_impl().is_some() {
49        return force_table_for_encode(cx.cx, value);
50    }
51
52    value.object().as_expr(cx.cx)
53}