use std::collections::HashSet;
use log::{debug, warn};
use crate::ast;
pub fn get_topic_triggers(brain: &ast::AST, topic: &ast::Topic, thats: bool) -> Vec<ast::Trigger> {
_get_topic_triggers(brain, topic, thats, 0, 0, false)
}
fn _get_topic_triggers(brain: &ast::AST, topic: &ast::Topic, thats: bool, depth: usize, inheritance: usize, inherited: bool) -> Vec<ast::Trigger> {
if depth > crate::DEFAULT_DEPTH {
warn!("Deep recursion while scanning topic inheritance!");
return Vec::new();
}
let mut triggers: Vec<ast::Trigger> = Vec::new();
let mut seen_triggers: HashSet<String> = HashSet::new();
let mut in_this_topic: Vec<ast::Trigger> = Vec::new();
let does_inherit = !topic.inherits.is_empty();
for trigger in topic.triggers.clone() {
if !thats {
if trigger.previous.is_empty() {
in_this_topic.push(trigger);
}
} else if !trigger.previous.is_empty() {
in_this_topic.push(trigger);
}
}
for mut trigger in in_this_topic {
seen_triggers.insert(trigger.trigger.clone());
if inheritance > 0 || does_inherit || inherited {
trigger.trigger = format!("{{inherits={}}}{}", inheritance, trigger.trigger);
}
triggers.push(trigger);
}
if !topic.includes.is_empty() {
for topic_name in topic.includes.keys() {
debug!("Topic {} includes {:?}", topic.name, topic_name);
let subtopic = brain.topics.get(topic_name).unwrap();
let append = _get_topic_triggers(brain, subtopic, thats, depth+1, inheritance, false);
for t in append {
if !seen_triggers.contains(&t.trigger) {
seen_triggers.insert(t.trigger.clone());
triggers.push(t);
}
}
}
}
if does_inherit {
for topic_name in topic.inherits.keys() {
debug!("Topic {} inherits {:?}", topic.name, topic_name);
let subtopic = brain.topics.get(topic_name).unwrap();
let append = _get_topic_triggers(brain, subtopic, thats, depth+1, inheritance+1, true);
triggers.extend(append);
}
}
triggers
}
pub fn get_topic_tree(brain: &ast::AST, topic: &ast::Topic, depth: usize) -> Vec<String> {
let mut topics: Vec<String> = Vec::new();
if depth > crate::DEFAULT_DEPTH {
warn!("Deep recursion while scanning topic tree!");
return topics;
}
topics.push(topic.name.clone());
for includes in topic.includes.keys() {
let subtopic = brain.topics.get(includes).unwrap();
topics.extend(get_topic_tree(brain, subtopic, depth+1));
}
for inherits in topic.inherits.keys() {
let subtopic = brain.topics.get(inherits).unwrap();
topics.extend(get_topic_tree(brain, subtopic, depth+1));
}
topics
}