use domain::{DataSourceId, Value, WidgetConfig, WidgetId, WidgetState}; use std::collections::HashMap; #[derive(Default)] pub struct DataProjection { current: HashMap, } impl DataProjection { pub fn new() -> Self { Self::default() } pub fn get_state(&self, widget_id: WidgetId) -> Option<&WidgetState> { self.current.get(&widget_id) } pub fn apply_poll_result( &mut self, data_source_id: DataSourceId, raw: &Value, widget_configs: &[WidgetConfig], ) -> Vec<(WidgetId, WidgetState)> { let mut changed = Vec::new(); for config in widget_configs { if config.data_source_id != data_source_id { continue; } let new_state = config.extract(raw); let is_changed = self .current .get(&config.id) .is_none_or(|prev| *prev != new_state); if is_changed { self.current.insert(config.id, new_state.clone()); changed.push((config.id, new_state)); } } changed } }