chaud_hot/workspace/graph/
index.rs1use crate::cargo::metadata::{Package, PackageName};
2use crate::util::CfgInto as _;
3use anyhow::{Context as _, Result, bail};
4use hashbrown::{HashMap, hash_map};
5
6#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
8pub struct KrateIdx(u32);
9
10impl KrateIdx {
11 #[inline]
12 #[must_use]
13 pub fn usize(self) -> usize {
14 self.0.cfg_into()
15 }
16}
17
18pub struct KrateIndex {
20 by_pkg: HashMap<PackageName, KrateIdx>,
21}
22
23impl KrateIndex {
24 pub fn new(pkgs: &[Package]) -> Result<Self> {
25 let mut pkgs: Vec<_> = pkgs.iter().collect();
26 pkgs.sort_unstable_by_key(|p| p.name());
28
29 let mut this = Self { by_pkg: HashMap::new() };
30
31 for pkg in pkgs {
32 this.insert(pkg).context("Failed to build package index")?;
33 }
34
35 Ok(this)
36 }
37
38 fn insert(&mut self, pkg: &Package) -> Result<()> {
39 let pkg_name = pkg.name().clone();
40
41 let next = KrateIdx(
42 self.by_pkg
43 .len()
44 .try_into()
45 .context("Crate idx overflowed `u32`")?,
46 );
47
48 match self.by_pkg.entry(pkg_name) {
49 hash_map::Entry::Occupied(entry) => bail!("Duplicate package name: {:?}", entry.key()),
50 hash_map::Entry::Vacant(entry) => entry.insert(next),
51 };
52
53 Ok(())
54 }
55
56 pub fn get_pkg(&self, name: &PackageName) -> Option<KrateIdx> {
57 self.by_pkg.get(name).copied()
58 }
59}