use std::collections::{HashMap, HashSet};
#[derive(Debug, Clone, Default)]
pub struct DependencyGraph {
state_to_segments: HashMap<String, HashSet<String>>,
segment_to_deps: HashMap<String, HashSet<String>>,
}
impl DependencyGraph {
pub fn new() -> Self {
Self::default()
}
pub fn add_dependency(&mut self, segment_id: &str, state_field: &str) {
self.state_to_segments
.entry(state_field.to_string())
.or_default()
.insert(segment_id.to_string());
self.segment_to_deps
.entry(segment_id.to_string())
.or_default()
.insert(state_field.to_string());
}
pub fn get_affected_segments(&self, dirty_fields: &[&str]) -> HashSet<String> {
let mut affected = HashSet::new();
for field in dirty_fields {
if let Some(segments) = self.state_to_segments.get(*field) {
affected.extend(segments.iter().cloned());
}
}
affected
}
pub fn get_deps_for_segment(&self, segment_id: &str) -> HashSet<String> {
self.segment_to_deps
.get(segment_id)
.cloned()
.unwrap_or_default()
}
pub fn all_state_fields(&self) -> HashSet<String> {
self.state_to_segments.keys().cloned().collect()
}
pub fn all_segments(&self) -> HashSet<String> {
self.segment_to_deps.keys().cloned().collect()
}
pub fn validate(&self, known_state: &[&str]) -> Vec<String> {
let known: HashSet<&str> = known_state.iter().copied().collect();
let mut unknown = Vec::new();
for deps in self.segment_to_deps.values() {
for dep in deps {
if !known.contains(dep.as_str()) && !unknown.contains(dep) {
unknown.push(dep.clone());
}
}
}
unknown.sort();
unknown
}
}