Skip to main content

sim_lib_web_bridge/
cookbook.rs

1//! Deterministic cookbook builders for web bridge recipes.
2
3use std::sync::Arc;
4
5use sim_kernel::{Cx, DefaultFactory, EagerPolicy, Expr, Symbol};
6use sim_lib_view::{
7    LensRegistry, UNIVERSAL_EDITOR_ID, UNIVERSAL_VIEW_ID, register_universal_default,
8};
9use sim_value::build::entry;
10
11use crate::{FixtureTransport, Session};
12
13/// Build the fixture-backed session descriptor used by the cookbook recipe.
14pub fn session_fixture_demo() -> Expr {
15    let mut cx = Cx::new(
16        Arc::new(EagerPolicy),
17        Arc::new(DefaultFactory),
18        sim_kernel::HandleSeed::new(0x5745_4201),
19    );
20    let registry = registry();
21    let mut session = Session::new(FixtureTransport::new().with(resource(), sample_value()));
22    let scene = session
23        .open(
24            &mut cx,
25            &registry,
26            Symbol::new("pane-1"),
27            resource(),
28            Symbol::new(UNIVERSAL_VIEW_ID),
29            Symbol::new(UNIVERSAL_EDITOR_ID),
30        )
31        .expect("fixture session opens");
32    debug_assert!(sim_lib_scene::validate_scene(&scene).is_ok());
33    Expr::Map(vec![
34        entry("transport", Expr::Symbol(Symbol::new("fixture"))),
35        entry("resource", Expr::Symbol(resource())),
36        entry("pane", Expr::Symbol(Symbol::new("pane-1"))),
37        entry("scene", scene),
38    ])
39}
40
41fn registry() -> LensRegistry {
42    let mut registry = LensRegistry::new();
43    register_universal_default(&mut registry, false);
44    registry
45}
46
47fn sample_value() -> Expr {
48    Expr::Map(vec![
49        entry("title", Expr::String("Fixture-backed session".to_owned())),
50        entry("status", Expr::Symbol(Symbol::new("modeled"))),
51    ])
52}
53
54fn resource() -> Symbol {
55    Symbol::qualified("doc", "cookbook")
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn session_fixture_demo_carries_valid_scene() {
64        let demo = session_fixture_demo();
65        let Expr::Map(entries) = demo else {
66            panic!("demo descriptor is a map")
67        };
68        let scene = entries
69            .iter()
70            .find_map(|(key, value)| {
71                matches!(key, Expr::Symbol(symbol) if &*symbol.name == "scene").then_some(value)
72            })
73            .expect("scene field exists");
74        sim_lib_scene::validate_scene(scene).expect("session scene validates");
75    }
76
77    #[test]
78    fn canonical_entry_matches_session_cookbook_field_shape() {
79        let value = Expr::Symbol(Symbol::new("fixture"));
80        assert_eq!(
81            entry("transport", value.clone()),
82            (Expr::Symbol(Symbol::new("transport")), value)
83        );
84    }
85}