use crate::view::NodeId;
use super::super::Workspace;
use super::super::id_index::NodeAddress;
impl Workspace {
pub(super) fn shift_rule_sets_down(&mut self, removed_idx: usize) {
let new_rs_count = self.config.service.rule_sets.len();
let mut stale: Vec<NodeAddress> = Vec::new();
stale.push(NodeAddress::RuleSet {
rule_set: removed_idx,
});
for old_idx in removed_idx..new_rs_count + 1 {
stale.push(NodeAddress::RuleSet { rule_set: old_idx });
}
let mut to_migrate: Vec<(NodeId, NodeAddress)> = Vec::new();
for (addr, &id) in self.ids.address_to_id.iter() {
match addr {
NodeAddress::RuleSet { rule_set } if *rule_set >= removed_idx => {
to_migrate.push((id, addr.clone()));
}
NodeAddress::Rule { rule_set, .. } if *rule_set >= removed_idx => {
to_migrate.push((id, addr.clone()));
}
NodeAddress::Respond { rule_set, .. } if *rule_set >= removed_idx => {
to_migrate.push((id, addr.clone()));
}
_ => {}
}
}
for (id, addr) in &to_migrate {
self.ids.address_to_id.remove(addr); self.ids.id_to_address.remove(id);
}
for (id, addr) in to_migrate {
let new_addr = match addr {
NodeAddress::RuleSet { rule_set } => {
if rule_set == removed_idx {
continue; }
NodeAddress::RuleSet {
rule_set: rule_set - 1,
}
}
NodeAddress::Rule { rule_set, rule } => {
if rule_set == removed_idx {
continue;
}
NodeAddress::Rule {
rule_set: rule_set - 1,
rule,
}
}
NodeAddress::Respond { rule_set, rule } => {
if rule_set == removed_idx {
continue;
}
NodeAddress::Respond {
rule_set: rule_set - 1,
rule,
}
}
other => other,
};
self.ids.id_to_address.insert(id, new_addr.clone());
self.ids.address_to_id.insert(new_addr, id);
}
}
pub(super) fn shift_rules_down(&mut self, rule_set_idx: usize, removed_rule_idx: usize) {
let mut to_migrate: Vec<(NodeId, NodeAddress)> = Vec::new();
for (addr, &id) in self.ids.address_to_id.iter() {
match addr {
NodeAddress::Rule { rule_set, rule }
if *rule_set == rule_set_idx && *rule >= removed_rule_idx =>
{
to_migrate.push((id, addr.clone()));
}
NodeAddress::Respond { rule_set, rule }
if *rule_set == rule_set_idx && *rule >= removed_rule_idx =>
{
to_migrate.push((id, addr.clone()));
}
_ => {}
}
}
for (id, addr) in &to_migrate {
self.ids.address_to_id.remove(addr); self.ids.id_to_address.remove(id);
}
for (id, addr) in to_migrate {
let new_addr = match addr {
NodeAddress::Rule { rule_set, rule } => {
if rule == removed_rule_idx {
continue;
}
NodeAddress::Rule {
rule_set,
rule: rule - 1,
}
}
NodeAddress::Respond { rule_set, rule } => {
if rule == removed_rule_idx {
continue;
}
NodeAddress::Respond {
rule_set,
rule: rule - 1,
}
}
other => other,
};
self.ids.id_to_address.insert(id, new_addr.clone());
self.ids.address_to_id.insert(new_addr, id);
}
}
pub(super) fn reorder_rule_ids(&mut self, rule_set_idx: usize, old_idx: usize, new_idx: usize) {
let rule_count = self.config.service.rule_sets[rule_set_idx].rules.len();
let mut rule_ids: Vec<Option<NodeId>> = (0..rule_count)
.map(|r| {
self.ids.id_for(NodeAddress::Rule {
rule_set: rule_set_idx,
rule: r,
})
})
.collect();
let mut resp_ids: Vec<Option<NodeId>> = (0..rule_count)
.map(|r| {
self.ids.id_for(NodeAddress::Respond {
rule_set: rule_set_idx,
rule: r,
})
})
.collect();
let moving_r = rule_ids.remove(old_idx);
rule_ids.insert(new_idx, moving_r);
let moving_resp = resp_ids.remove(old_idx);
resp_ids.insert(new_idx, moving_resp);
for r in 0..rule_count {
let rule_addr = NodeAddress::Rule {
rule_set: rule_set_idx,
rule: r,
};
let resp_addr = NodeAddress::Respond {
rule_set: rule_set_idx,
rule: r,
};
if let Some(prev_id) = self.ids.address_to_id.remove(&rule_addr) {
self.ids.id_to_address.remove(&prev_id);
}
if let Some(prev_id) = self.ids.address_to_id.remove(&resp_addr) {
self.ids.id_to_address.remove(&prev_id);
}
}
for (r, id_opt) in rule_ids.into_iter().enumerate() {
let addr = NodeAddress::Rule {
rule_set: rule_set_idx,
rule: r,
};
let id = id_opt.unwrap_or_else(NodeId::new);
self.ids.id_to_address.insert(id, addr.clone());
self.ids.address_to_id.insert(addr, id);
}
for (r, id_opt) in resp_ids.into_iter().enumerate() {
let addr = NodeAddress::Respond {
rule_set: rule_set_idx,
rule: r,
};
let id = id_opt.unwrap_or_else(NodeId::new);
self.ids.id_to_address.insert(id, addr.clone());
self.ids.address_to_id.insert(addr, id);
}
}
}