Skip to main content

extend_store_collections/
extend_store_collections.rs

1//! Arrays and maps — chaining, closures, and nested construction.
2//!
3//! ArrayHandle::push and MapHandle::insert return Result<&mut Self>, enabling
4//! fluent chaining with `?`. The Store also provides with_array/with_map
5//! closure methods that scope the handle lifetime automatically.
6
7use panopticon_core::extend::{Store, Value};
8
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10    let mut store = Store::new();
11
12    // --- Chainable push ---
13    // push() accepts V: Into<StoreEntry>. The blanket impl
14    // `From<T: Into<Value>> for StoreEntry` means primitives work directly.
15    let mut arr = store.define_array("numbers")?.push(1)?.push(2)?.push(3)?;
16
17    let items = store.get("numbers")?.as_array()?;
18    println!("numbers: len={}", items.len());
19    assert_eq!(items.len(), 3);
20
21    // --- Chainable insert ---
22    // insert() accepts K: Into<String> and V: Into<StoreEntry>.
23    let mut map = store.define_map("config")?;
24    map.insert("host", "localhost")?
25        .insert("port", 8080i64)?
26        .insert("debug", true)?;
27
28    let host = store.get("config")?.get_key("host")?.get_value()?;
29    println!("config.host = {host:?}");
30
31    // --- Closure API on Store ---
32    // with_array scopes the handle so you don't need an explicit drop.
33    store.with_array("tags", |arr| {
34        arr.push("rust")?.push("pipeline")?.push("store")?;
35        Ok(())
36    })?;
37
38    let tags = store.get("tags")?.as_array()?;
39    println!("tags: len={}", tags.len());
40
41    store.with_map("metadata", |map| {
42        map.insert("version", "0.1.0")?.insert("stable", false)?;
43        Ok(())
44    })?;
45
46    let version = store.get("metadata")?.get_key("version")?.get_value()?;
47    println!("metadata.version = {version:?}");
48
49    // --- Nested construction via MapHandle closures ---
50    // with_array and with_map on MapHandle let you build nested structures
51    // without manually managing sub-handles.
52    store.with_map("server", |map| {
53        map.insert("name", "prod-01")?;
54
55        map.with_array("ports", |arr| {
56            arr.push(80)?.push(443)?;
57            Ok(())
58        })?;
59
60        map.with_map("tls", |tls| {
61            tls.insert("enabled", true)?
62                .insert("cert_path", "/etc/ssl/cert.pem")?;
63            Ok(())
64        })?;
65
66        Ok(())
67    })?;
68
69    let tls_enabled = store
70        .get("server")?
71        .get_key("tls")?
72        .get_key("enabled")?
73        .get_value()?;
74    println!("server.tls.enabled = {tls_enabled:?}");
75
76    // --- push_map on ArrayHandle ---
77    // Builds an array of maps — the most common pattern for tabular results.
78    let mut arr = store.define_array("users")?;
79    {
80        let mut user = arr.push_map()?;
81        user.insert("name", "Alice")?.insert("role", "admin")?;
82    }
83    {
84        let mut user = arr.push_map()?;
85        user.insert("name", "Bob")?.insert("role", "viewer")?;
86    }
87
88    let bob_role = store
89        .get("users")?
90        .get_index(1)?
91        .get_key("role")?
92        .get_value()?;
93    println!("users[1].role = {bob_role:?}");
94    assert_eq!(bob_role, &Value::Text("viewer".into()));
95
96    println!("store_collections: ok");
97    Ok(())
98}