sim_lib_expr_tree/
handle.rs1use std::{
2 collections::BTreeMap,
3 sync::{Arc, Mutex},
4};
5
6use sim_kernel::{Cx, Object, ObjectCompat, Result};
7
8use crate::runtime::TreeState;
9
10const MAX_STORAGE_NAME_BYTES: usize = 256;
11
12#[derive(Clone)]
18pub struct TreeHandle {
19 pub(crate) state: Arc<Mutex<TreeState>>,
20}
21
22impl TreeHandle {
23 fn new(state: Arc<Mutex<TreeState>>) -> Self {
24 Self { state }
25 }
26}
27
28impl Object for TreeHandle {
29 fn display(&self, _cx: &mut Cx) -> Result<String> {
30 let state = self
31 .state
32 .lock()
33 .map_err(|_| sim_kernel::Error::Eval("expression-tree state poisoned".to_owned()))?;
34 Ok(format!("#<expr-tree {}>", state.storage_name()))
35 }
36
37 fn as_any(&self) -> &dyn std::any::Any {
38 self
39 }
40}
41
42impl ObjectCompat for TreeHandle {}
43
44pub(crate) struct TreeRuntime {
45 stores: Mutex<BTreeMap<String, Arc<Mutex<TreeState>>>>,
46}
47
48impl TreeRuntime {
49 pub(crate) fn new() -> Self {
50 Self {
51 stores: Mutex::new(BTreeMap::new()),
52 }
53 }
54
55 pub(crate) fn open(
56 &self,
57 cx: &Cx,
58 storage_name: &str,
59 ) -> std::result::Result<TreeHandle, String> {
60 if storage_name.is_empty() || storage_name.len() > MAX_STORAGE_NAME_BYTES {
61 return Err(format!(
62 "storage name must contain 1..={MAX_STORAGE_NAME_BYTES} bytes"
63 ));
64 }
65 let mut stores = self
66 .stores
67 .lock()
68 .map_err(|_| "expression-tree storage registry poisoned".to_owned())?;
69 let state = match stores.get(storage_name) {
70 Some(state) => Arc::clone(state),
71 None => {
72 let state = Arc::new(Mutex::new(TreeState::new(cx, storage_name.to_owned())?));
73 stores.insert(storage_name.to_owned(), Arc::clone(&state));
74 state
75 }
76 };
77 Ok(TreeHandle::new(state))
78 }
79}