Skip to main content

sim_lib_expr_tree/
inspect.rs

1//! Bounded, read-only inspection of a live expression-tree handle.
2
3use sim_expr_tree_calc::{CalcReceipt, CalcStatus, EncodedFace};
4use sim_kernel::{Error, Result};
5
6use crate::TreeHandle;
7
8/// Kind of one immediate expression-tree entry.
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub enum TreeEntryKind {
11    /// A finite namespace directory.
12    Directory,
13    /// A source cell.
14    Cell,
15    /// A mounted directory or table boundary.
16    Mount,
17}
18
19/// Bounded identity facts for one immediate expression-tree entry.
20#[derive(Clone, Debug, Eq, PartialEq)]
21pub struct TreeEntryInspection {
22    /// Canonical absolute path.
23    pub path: String,
24    /// Final canonical path segment.
25    pub name: String,
26    /// Entry kind.
27    pub kind: TreeEntryKind,
28    /// Source revision for a cell, or zero for a directory.
29    pub revision: u64,
30}
31
32/// Non-evaluating, already-bounded facts for one expression-tree cell.
33#[derive(Clone, Debug, Eq, PartialEq)]
34pub struct TreeCellInspection {
35    /// Canonical absolute path.
36    pub path: String,
37    /// Bounded source face produced by inherited codec policy.
38    pub source: EncodedFace,
39    /// Bounded result face produced by inherited codec policy.
40    pub result: EncodedFace,
41    /// Current non-evaluating calculation status.
42    pub status: CalcStatus,
43    /// Current source revision.
44    pub source_revision: u64,
45    /// Latest bounded receipt, when any.
46    pub receipt: Option<CalcReceipt>,
47    /// Stable effective-policy badges.
48    pub policy_badges: Vec<String>,
49}
50
51impl TreeHandle {
52    /// Returns the durable storage name without exposing the live backend.
53    pub fn storage_name(&self) -> Result<String> {
54        self.with_state(|state| Ok(state.storage_name().to_owned()))
55    }
56
57    /// Lists bounded immediate entry facts below `path`.
58    pub fn inspect_entries(&self, path: &str) -> Result<Vec<TreeEntryInspection>> {
59        self.with_state(|state| state.inspect_entries(path))
60    }
61
62    /// Returns bounded, non-evaluating facts for one cell.
63    pub fn inspect_cell(&self, path: &str) -> Result<TreeCellInspection> {
64        self.with_state(|state| state.inspect_cell(path))
65    }
66
67    /// Injects optional human wall-clock observations into future receipts.
68    ///
69    /// Logical ticks and revisions remain the only freshness authority.
70    pub fn set_wall_clock<F>(&self, clock: F) -> Result<()>
71    where
72        F: Fn() -> Option<u64> + Send + Sync + 'static,
73    {
74        self.with_state(|state| {
75            state.set_wall_clock(clock);
76            Ok(())
77        })
78    }
79
80    fn with_state<T>(
81        &self,
82        action: impl FnOnce(&mut crate::runtime::TreeState) -> std::result::Result<T, String>,
83    ) -> Result<T> {
84        let mut state = self
85            .state
86            .lock()
87            .map_err(|_| Error::Eval("expression-tree state poisoned".to_owned()))?;
88        action(&mut state).map_err(Error::Eval)
89    }
90}