Skip to main content

sim_lib_web_layout/
value.rs

1//! The workspace value and small map helpers.
2//!
3//! The whole workspace is one SIM value: a map of panes, the focused pane, the
4//! experience mode, the session and history refs, and palette state. It is
5//! built from kernel `Expr` only, so it round-trips through any general codec
6//! and can be saved, shared, versioned, diffed, and restored as data. Layout is
7//! data; restoring a session is decoding a value.
8
9use sim_kernel::{Expr, Symbol};
10
11// The generic `Expr` constructors and accessors live in `sim-value`; these
12// re-exports preserve this module's public names and signatures so consumers
13// (`palette`, `layout`, ...) keep calling `value::int`/`map`/`key`/`get`/`set`/
14// `as_int` unchanged.
15pub use sim_value::access::as_i64 as as_int;
16pub use sim_value::access::field as get;
17pub use sim_value::access::set;
18pub use sim_value::build::sym as key;
19pub use sim_value::build::{int, map};
20
21/// The workspace class symbol carried in the `class` field.
22pub const WORKSPACE_CLASS: &str = "web/Workspace";
23
24/// A fresh, empty workspace in `mode` with no panes.
25pub fn new_workspace(mode: &str) -> Expr {
26    map(vec![
27        ("class", Expr::Symbol(Symbol::qualified("web", "Workspace"))),
28        ("mode", Expr::Symbol(Symbol::new(mode))),
29        ("panes", Expr::List(Vec::new())),
30        ("focus", Expr::Nil),
31        ("session", Expr::Nil),
32        ("history", Expr::Nil),
33        (
34            "palette",
35            map(vec![
36                ("open", Expr::Bool(false)),
37                ("query", Expr::String(String::new())),
38            ]),
39        ),
40    ])
41}
42
43/// The workspace mode symbol, if set.
44pub fn mode(workspace: &Expr) -> Option<Symbol> {
45    match get(workspace, "mode") {
46        Some(Expr::Symbol(symbol)) => Some(symbol.clone()),
47        _ => None,
48    }
49}
50
51/// The list of pane records.
52pub fn panes(workspace: &Expr) -> Vec<Expr> {
53    match get(workspace, "panes") {
54        Some(Expr::List(items)) => items.clone(),
55        _ => Vec::new(),
56    }
57}
58
59/// The focused pane id, if any.
60pub fn focus(workspace: &Expr) -> Option<Symbol> {
61    match get(workspace, "focus") {
62        Some(Expr::Symbol(symbol)) => Some(symbol.clone()),
63        _ => None,
64    }
65}
66
67/// Set the panes list.
68pub fn with_panes(workspace: &Expr, panes: Vec<Expr>) -> Expr {
69    set(workspace, "panes", Expr::List(panes))
70}