Skip to main content

sim_table_hash/
backend.rs

1//! Library registration for the hash-map table backend: the [`HashBackend`]
2//! `TableBackend` implementation, the [`HashTableLib`] manifest, and the
3//! [`install_hash_table_lib`] entry point.
4
5use std::sync::Arc;
6
7use sim_kernel::{
8    AbiVersion, Cx, Dependency, Export, Lib, LibManifest, LibTarget, Linker, Result, Symbol,
9    TableBackend, Value, Version,
10};
11
12use crate::HashTable;
13
14/// Table backend that constructs [`HashTable`] objects for the `hash` backend
15/// name.
16///
17/// Registered with the context table registry by [`install_hash_table_lib`] so
18/// that table operations resolved against the `hash` backend build hash-map
19/// tables.
20pub struct HashBackend;
21
22impl TableBackend for HashBackend {
23    fn name(&self) -> &str {
24        "hash"
25    }
26
27    fn new_table(&self, cx: &mut Cx, entries: Vec<(Symbol, Value)>) -> Result<Value> {
28        cx.factory()
29            .opaque(Arc::new(HashTable::with_entries(entries)))
30    }
31}
32
33/// Loadable library manifest for the hash table backend.
34///
35/// Declares the `table/hash` library identity and ABI; backend registration is
36/// performed separately by [`install_hash_table_lib`].
37pub struct HashTableLib;
38
39impl Lib for HashTableLib {
40    fn manifest(&self) -> LibManifest {
41        LibManifest {
42            id: Symbol::qualified("table", "hash"),
43            version: Version(env!("CARGO_PKG_VERSION").to_owned()),
44            abi: AbiVersion { major: 0, minor: 1 },
45            target: LibTarget::HostRegistered,
46            requires: Vec::<Dependency>::new(),
47            capabilities: Vec::new(),
48            exports: Vec::<Export>::new(),
49        }
50    }
51
52    fn load(&self, _cx: &mut sim_kernel::LoadCx, _linker: &mut Linker<'_>) -> Result<()> {
53        Ok(())
54    }
55}
56
57/// Register the [`HashBackend`] and load the [`HashTableLib`] into `cx`.
58///
59/// Idempotent: if the `table/hash` library is already present the call is a
60/// no-op. After installation the `hash` backend can be selected as the active
61/// table backend via the context table registry.
62pub fn install_hash_table_lib(cx: &mut Cx) -> Result<()> {
63    if cx
64        .registry()
65        .lib(&Symbol::qualified("table", "hash"))
66        .is_some()
67    {
68        return Ok(());
69    }
70    cx.table_registry_mut().register(Arc::new(HashBackend));
71    cx.load_lib(&HashTableLib).map(|_| ())
72}