sim-codec-bitwise-base64 0.1.4

SIM workspace package for sim codec bitwise base64.
Documentation
use sim_codec_binary_base64::{decode_base64_with_limits, encode_base64};
use sim_kernel::{Args, Callable, Cx, Error, Expr, Object, ObjectCompat, Result, Symbol, Value};
use sim_value::build::entry as field;

pub(crate) fn roundtrip_report_symbol() -> Symbol {
    Symbol::qualified("bitwise-base64", "roundtrip-report")
}

pub(crate) struct BitwiseBase64RoundtripReport;

impl Callable for BitwiseBase64RoundtripReport {
    fn call(&self, cx: &mut Cx, args: Args) -> Result<Value> {
        if !args.values().is_empty() {
            return Err(Error::Eval(format!(
                "{} expects no arguments",
                roundtrip_report_symbol()
            )));
        }
        let sample = sample_expr();
        let frame = sim_codec_bitwise::encode_frame(&sample)?;
        let text = encode_base64(&frame.0);
        let bytes = decode_base64_with_limits(
            sim_kernel::CodecId(0),
            &text,
            sim_codec::DecodeLimits::default(),
        )?;
        let (_, decoded) = sim_codec_bitwise::decode_frame(sim_kernel::CodecId(0), &bytes)?;
        let report = Expr::Map(vec![
            field(
                "kind",
                Expr::Symbol(Symbol::qualified("codec", "roundtrip")),
            ),
            field("codec", Expr::String("codec/bitwise-base64".to_owned())),
            field("wire", Expr::String("base64 text over vbits".to_owned())),
            field("encoded-chars", Expr::String(text.len().to_string())),
            field("decoded", decoded.clone()),
            field("roundtrip", Expr::Bool(decoded.canonical_eq(&sample))),
            field(
                "lanes",
                Expr::List(vec![
                    Expr::String("encode".to_owned()),
                    Expr::String("decode".to_owned()),
                ]),
            ),
        ]);
        cx.factory().expr(report)
    }
}

impl Object for BitwiseBase64RoundtripReport {
    fn display(&self, _cx: &mut Cx) -> Result<String> {
        Ok(roundtrip_report_symbol().to_string())
    }

    fn as_any(&self) -> &dyn std::any::Any {
        self
    }
}

impl ObjectCompat for BitwiseBase64RoundtripReport {
    fn as_callable(&self) -> Option<&dyn Callable> {
        Some(self)
    }
}

fn sample_expr() -> Expr {
    Expr::List(vec![
        Expr::Symbol(Symbol::qualified("codec", "bitwise-base64-demo")),
        Expr::String("text wrapper".to_owned()),
        Expr::Bool(true),
    ])
}