use std::borrow::Cow;
use rkyv::collections::swiss_table::ArchivedHashMap;
use rkyv::rancor::Panic;
use rkyv::util::AlignedVec;
use rustc_hash::FxHashMap;
use rustdoc_types::{ArchivedId, ArchivedItem, Item};
#[derive(Debug, Clone)]
pub enum CrateItemIndex {
Eager(EagerCrateItemIndex),
Lazy(LazyCrateItemIndex),
}
impl CrateItemIndex {
pub fn get(&self, id: &rustdoc_types::Id) -> Option<Cow<'_, Item>> {
match self {
Self::Eager(index) => index.index.get(id).map(Cow::Borrowed),
Self::Lazy(index) => {
let item = index.get_deserialized(id)?;
Some(Cow::Owned(item))
}
}
}
}
#[derive(Debug, Clone)]
pub struct EagerCrateItemIndex {
#[allow(clippy::disallowed_types)]
pub index: FxHashMap<rustdoc_types::Id, Item>,
}
#[derive(Debug, Clone)]
pub struct LazyCrateItemIndex {
pub bytes: AlignedVec,
}
impl LazyCrateItemIndex {
#[inline]
fn archived(&self) -> &ArchivedHashMap<ArchivedId, ArchivedItem> {
unsafe { rkyv::access_unchecked::<ArchivedHashMap<ArchivedId, ArchivedItem>>(&self.bytes) }
}
pub fn get(&self, id: &rustdoc_types::Id) -> Option<&ArchivedItem> {
self.archived().get(&ArchivedId(id.0.into()))
}
pub fn get_deserialized(&self, id: &rustdoc_types::Id) -> Option<Item> {
let archived = self.get(id)?;
Some(rkyv::deserialize::<Item, Panic>(archived).unwrap())
}
}