Skip to main content

sim_lib_expr_tree/
inspect.rs

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