use std::collections::{HashMap, HashSet};
#[derive(Debug, Clone)]
pub struct ComputedState {
computed_values: HashMap<usize, String>,
dependencies: HashMap<usize, Vec<usize>>,
computed_fields: HashSet<usize>,
}
impl ComputedState {
pub fn new() -> Self {
Self {
computed_values: HashMap::new(),
dependencies: HashMap::new(),
computed_fields: HashSet::new(),
}
}
pub fn register_computed_field(&mut self, field_index: usize, mut dependencies: Vec<usize>) {
dependencies.sort_unstable();
dependencies.dedup();
self.computed_fields.insert(field_index);
self.dependencies.insert(field_index, dependencies);
}
pub fn is_computed_field(&self, field_index: usize) -> bool {
self.computed_fields.contains(&field_index)
}
pub fn get_computed_value(&self, field_index: usize) -> Option<&String> {
self.computed_values.get(&field_index)
}
pub fn set_computed_value(&mut self, field_index: usize, value: String) {
self.computed_values.insert(field_index, value);
}
pub fn fields_to_recompute(&self, changed_field: usize) -> Vec<usize> {
self.dependencies
.iter()
.filter_map(|(field, deps)| {
if deps.contains(&changed_field) {
Some(*field)
} else {
None
}
})
.collect()
}
pub fn computed_fields(&self) -> impl Iterator<Item = usize> + '_ {
self.computed_fields.iter().copied()
}
}
impl Default for ComputedState {
fn default() -> Self {
Self::new()
}
}