//! Shallow state diffing — records opaque "modified" markers so the TUI //! knows to re-render without computing fine-grained deltas. use serde::{Deserialize, Serialize}; /// A collection of changes tracking which parts of app state have been /// modified since the last render sweep. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct StateDiff { changes: Vec, } /// A single named change — currently always carries a flat `"."` path /// and `"modified"` kind because the system does not track granular diffs. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Change { pub path: String, pub kind: String, } impl StateDiff { /// Create an empty diff. pub fn new() -> Self { StateDiff { changes: Vec::new() } } /// Record a change at `path` of the given `kind`. pub fn add_change(&mut self, path: String, kind: String) { self.changes.push(Change { path, kind }); } /// Return true if no changes have been recorded. pub fn is_empty(&self) -> bool { self.changes.is_empty() } /// Remove all recorded changes. pub fn clear(&mut self) { self.changes.clear(); } } /// Compute a shallow diff between two serialised state values. /// /// Flow: compare with `==`, return an empty vec if equal, otherwise /// return a single `Change { ".", "modified" }`. /// /// Why: a placeholder — the current rendering model re-validates the /// whole viewport every frame, so fine-grained diffs are unnecessary. /// /// Return: the list of changes (always 0 or 1 entry). pub fn compute_diff(before: &serde_json::Value, after: &serde_json::Value) -> Vec { if before == after { return Vec::new(); } vec![Change { path: ".".to_string(), kind: "modified".to_string(), }] }