Skip to main content

sim_table_lazy/
backend.rs

1//! Library registration for the lazy table backend: the [`LazyBackend`]
2//! `TableBackend` implementation, the [`LazyTableLib`] manifest, and the
3//! [`install_lazy_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::LazyTable;
13
14/// Table backend that constructs [`LazyTable`] objects for the `lazy` backend
15/// name.
16///
17/// Registered with the context table registry by [`install_lazy_table_lib`].
18/// Tables built through this backend hold the supplied entries eagerly; lazy
19/// loaders are added afterwards via [`LazyTable::put_lazy`].
20pub struct LazyBackend;
21
22impl TableBackend for LazyBackend {
23    fn name(&self) -> &str {
24        "lazy"
25    }
26
27    fn new_table(&self, cx: &mut Cx, entries: Vec<(Symbol, Value)>) -> Result<Value> {
28        cx.factory()
29            .opaque(Arc::new(LazyTable::with_entries(entries)))
30    }
31}
32
33/// Loadable library manifest for the lazy table backend.
34///
35/// Declares the `table/lazy` library identity and ABI; backend registration is
36/// performed separately by [`install_lazy_table_lib`].
37pub struct LazyTableLib;
38
39impl Lib for LazyTableLib {
40    fn manifest(&self) -> LibManifest {
41        LibManifest {
42            id: Symbol::qualified("table", "lazy"),
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 [`LazyBackend`] and load the [`LazyTableLib`] into `cx`.
58///
59/// Idempotent: if the `table/lazy` library is already present the call is a
60/// no-op. After installation the `lazy` backend can be selected as the active
61/// table backend via the context table registry.
62pub fn install_lazy_table_lib(cx: &mut Cx) -> Result<()> {
63    let lib_id = Symbol::qualified("table", "lazy");
64    if cx.registry().lib(&lib_id).is_some() {
65        return Ok(());
66    }
67    cx.table_registry_mut().register(Arc::new(LazyBackend));
68    cx.load_lib(&LazyTableLib).map(|_| ())
69}