sim-table-hash 0.1.0

SIM workspace package for sim table hash.
Documentation
use std::sync::Arc;

use sim_kernel::{
    Cx, DefaultFactory, NoopEvalPolicy, ObjectEncoding, Symbol, Table, read_construct_capability,
};

use crate::{
    HashBackend, HashTable, HashTableDescriptor, hash_table_class_symbol, install_hash_table_lib,
};

fn test_cx() -> Cx {
    Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory))
}

#[test]
fn hash_table_lookup() {
    let mut cx = test_cx();
    let one = cx.factory().bool(true).unwrap();
    let two = cx.factory().nil().unwrap();
    let table = HashTable::with_entries(vec![
        (Symbol::new("a"), one.clone()),
        (Symbol::new("b"), two),
    ]);

    assert_eq!(table.len(&mut cx).unwrap(), 2);
    assert!(table.has(&mut cx, Symbol::new("a")).unwrap());
    assert_eq!(table.get(&mut cx, Symbol::new("a")).unwrap(), one);
}

#[test]
fn install_registers_hash_backend() {
    let mut cx = test_cx();
    install_hash_table_lib(&mut cx).unwrap();
    cx.table_registry_mut().set_active("hash").unwrap();

    let backend = cx.table_registry().active();
    assert_eq!(backend, "hash");

    let name = <HashBackend as sim_kernel::TableBackend>::name(&HashBackend);
    assert_eq!(name, "hash");
}

#[test]
fn hash_table_citizen_round_trips_as_descriptor() {
    let mut cx = test_cx();
    cx.load_lib(&sim_citizen::CitizenLib::all()).unwrap();
    cx.grant(read_construct_capability());
    let value = cx.factory().string("value".to_owned()).unwrap();
    let table = HashTable::with_entries(vec![(Symbol::new("key"), value)]);
    let original = cx.factory().opaque(std::sync::Arc::new(table)).unwrap();

    sim_citizen::check_value_fixture(&mut cx, original.clone()).unwrap();

    let ObjectEncoding::Constructor { args, .. } = original
        .object()
        .as_object_encoder()
        .unwrap()
        .object_encoding(&mut cx)
        .unwrap()
    else {
        panic!("expected constructor encoding");
    };
    let args = args
        .iter()
        .map(|arg| sim_citizen::value_from_expr(&mut cx, arg))
        .collect::<sim_kernel::Result<Vec<_>>>()
        .unwrap();
    let decoded = cx.read_construct(&hash_table_class_symbol(), args).unwrap();

    assert!(
        decoded
            .object()
            .as_any()
            .downcast_ref::<HashTableDescriptor>()
            .is_some()
    );
    assert!(decoded.object().as_table_impl().is_none());
}