sim-codec-lisp 0.1.0-rc.1

SIM workspace package for sim codec lisp.
Documentation
use super::*;

use sim_codec::{
    DecodePosition, DecodedForm, decode_datum_with_codec, decode_default_with_codec,
    decode_term_with_codec, encode_datum_with_codec,
};
use sim_kernel::{Datum, Ref, Term};

fn symbol() -> Symbol {
    Symbol::qualified("codec", "lisp")
}

fn sample_datum() -> Datum {
    Datum::Node {
        tag: Symbol::qualified("demo", "wire"),
        fields: vec![
            (Symbol::new("name"), Datum::String("sample".to_owned())),
            (
                Symbol::new("payload"),
                Datum::List(vec![
                    Datum::Symbol(Symbol::qualified("math", "pi")),
                    Datum::Bytes(vec![1, 2, 3]),
                ]),
            ),
        ],
    }
}

#[test]
fn lisp_datum_roundtrip_preserves_content_id() {
    let mut cx = cx();
    register_lisp_codec(&mut cx);
    let datum = sample_datum();
    let content_id = datum.content_id().unwrap();

    let output = encode_datum_with_codec(&mut cx, &symbol(), &datum, Default::default())
        .unwrap()
        .into_text()
        .unwrap();
    let decoded = decode_datum_with_codec(
        &mut cx,
        &symbol(),
        Input::Text(output),
        ReadPolicy::default(),
    )
    .unwrap();

    assert_eq!(decoded, datum);
    assert_eq!(decoded.content_id().unwrap(), content_id);
}

#[test]
fn lisp_default_decode_uses_term_in_eval_and_datum_in_data() {
    let mut cx = cx();
    register_lisp_codec(&mut cx);

    let eval = decode_default_with_codec(
        &mut cx,
        &symbol(),
        Input::Text("(math/add 1 2)".to_owned()),
        ReadPolicy::default(),
        DecodePosition::Eval,
    )
    .unwrap();
    assert!(matches!(eval, DecodedForm::Term(Term::Call { .. })));

    let data = decode_default_with_codec(
        &mut cx,
        &symbol(),
        Input::Text("(math/add 1 2)".to_owned()),
        ReadPolicy::default(),
        DecodePosition::Data,
    )
    .unwrap();
    assert!(matches!(data, DecodedForm::Datum(Datum::List(_))));

    let quote = decode_default_with_codec(
        &mut cx,
        &symbol(),
        Input::Text("(math/add 1 2)".to_owned()),
        ReadPolicy::default(),
        DecodePosition::Quote,
    )
    .unwrap();
    assert!(matches!(quote, DecodedForm::Datum(Datum::List(_))));
}

#[test]
fn lisp_term_decode_lowers_list_call_surface() {
    let mut cx = cx();
    register_lisp_codec(&mut cx);

    let term = decode_term_with_codec(
        &mut cx,
        &symbol(),
        Input::Text("(math/add 1 2)".to_owned()),
        ReadPolicy::default(),
    )
    .unwrap();

    let Term::Call { target, args } = term else {
        panic!("expected call term");
    };
    assert_eq!(
        *target,
        Term::Ref(Ref::Symbol(Symbol::qualified("math", "add")))
    );
    assert_eq!(args.len(), 2);
}