1use rustc_hash::FxHashMap;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
8pub struct FileId(u32);
9
10#[derive(Debug, Default)]
15pub struct FileIdMap {
16 path_to_id: FxHashMap<Box<str>, FileId>,
17 id_to_path: Vec<Box<str>>,
18}
19
20impl FileIdMap {
21 pub fn new() -> Self {
22 Self::default()
23 }
24
25 pub fn assign_or_get(&mut self, path: &str) -> FileId {
27 if let Some(&id) = self.path_to_id.get(path) {
28 return id;
29 }
30 let id = FileId(self.id_to_path.len() as u32);
31 let key: Box<str> = Box::from(path);
32 self.id_to_path.push(key.clone());
33 self.path_to_id.insert(key, id);
34 id
35 }
36
37 pub fn get(&self, path: &str) -> Option<FileId> {
39 self.path_to_id.get(path).copied()
40 }
41
42 pub fn path(&self, id: FileId) -> Option<&str> {
44 self.id_to_path.get(id.0 as usize).map(|s| s.as_ref())
45 }
46
47 pub fn len(&self) -> usize {
48 self.id_to_path.len()
49 }
50
51 pub fn is_empty(&self) -> bool {
52 self.id_to_path.is_empty()
53 }
54
55 pub fn iter(&self) -> impl Iterator<Item = (FileId, &str)> {
57 self.id_to_path
58 .iter()
59 .enumerate()
60 .map(|(i, p)| (FileId(i as u32), p.as_ref()))
61 }
62}