use crate::{data::PARENT_CLASSES, ObjectId};
use fnv::FnvHashMap;
use super::normalize_object;
pub(crate) struct ObjectIndex<'a> {
name_index: FnvHashMap<&'a str, ObjectId>,
}
impl<'a> ObjectIndex<'a> {
pub(crate) fn new(objects: &'a [String]) -> Self {
let mut name_index: FnvHashMap<&str, ObjectId> = FnvHashMap::default();
for (i, name) in objects.iter().enumerate() {
let val = ObjectId(i as i32);
name_index.entry(name.as_str()).or_insert(val);
}
Self { name_index }
}
pub(crate) fn by_name(&self, name: &str) -> Option<ObjectId> {
self.name_index.get(name).copied()
}
pub(crate) fn hierarchy<'b>(&'b self, name: &'b str) -> AncestorIterator<'a, 'b> {
AncestorIterator { name, index: self }
}
}
pub(crate) struct AncestorIterator<'a, 'b> {
name: &'b str,
index: &'a ObjectIndex<'b>,
}
impl Iterator for AncestorIterator<'_, '_> {
type Item = ObjectId;
fn next(&mut self) -> Option<Self::Item> {
loop {
let current = self.name;
self.name = PARENT_CLASSES.get(normalize_object(self.name))?;
if let sme @ Some(_) = self.index.by_name(current) {
return sme;
}
}
}
}