use rustc_hash::FxHashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct FileId(u32);
#[derive(Debug, Default)]
pub struct FileIdMap {
path_to_id: FxHashMap<Box<str>, FileId>,
id_to_path: Vec<Box<str>>,
}
impl FileIdMap {
pub fn new() -> Self {
Self::default()
}
pub fn assign_or_get(&mut self, path: &str) -> FileId {
if let Some(&id) = self.path_to_id.get(path) {
return id;
}
let id = FileId(self.id_to_path.len() as u32);
let key: Box<str> = Box::from(path);
self.id_to_path.push(key.clone());
self.path_to_id.insert(key, id);
id
}
pub fn get(&self, path: &str) -> Option<FileId> {
self.path_to_id.get(path).copied()
}
pub fn path(&self, id: FileId) -> Option<&str> {
self.id_to_path.get(id.0 as usize).map(|s| s.as_ref())
}
pub fn len(&self) -> usize {
self.id_to_path.len()
}
pub fn is_empty(&self) -> bool {
self.id_to_path.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = (FileId, &str)> {
self.id_to_path
.iter()
.enumerate()
.map(|(i, p)| (FileId(i as u32), p.as_ref()))
}
}