use std::cmp::Ordering;
use std::collections::BTreeSet;
use ahash::HashMap;
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ImportIndex {
pub modules: HashMap<rustdoc_types::Id, ImportIndexEntry>,
pub items: HashMap<rustdoc_types::Id, ImportIndexEntry>,
pub re_export2parent_module: HashMap<rustdoc_types::Id, rustdoc_types::Id>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ImportIndexEntry {
pub public_paths: BTreeSet<SortablePath>,
pub private_paths: BTreeSet<SortablePath>,
pub defined_at: Option<Vec<String>>,
}
pub enum EntryVisibility {
Public,
Private,
}
impl ImportIndexEntry {
pub fn empty() -> Self {
Self {
public_paths: BTreeSet::new(),
private_paths: BTreeSet::new(),
defined_at: None,
}
}
pub fn new(path: Vec<String>, visibility: EntryVisibility, is_definition: bool) -> Self {
let mut entry = Self::empty();
if is_definition {
entry.defined_at = Some(path.clone());
}
match visibility {
EntryVisibility::Public => entry.public_paths.insert(SortablePath(path)),
EntryVisibility::Private => entry.private_paths.insert(SortablePath(path)),
};
entry
}
pub fn insert_private(&mut self, path: Vec<String>) {
self.private_paths.insert(SortablePath(path));
}
pub fn insert(&mut self, path: Vec<String>, visibility: EntryVisibility) {
match visibility {
EntryVisibility::Public => self.public_paths.insert(SortablePath(path)),
EntryVisibility::Private => self.private_paths.insert(SortablePath(path)),
};
}
pub fn canonical_path(&self) -> &[String] {
if let Some(SortablePath(p)) = self.public_paths.first() {
return p;
}
if let Some(SortablePath(p)) = self.private_paths.first() {
return p;
}
unreachable!("There must be at least one path associated to an import index entry")
}
pub fn paths(&self) -> impl Iterator<Item = &[String]> {
self.public_paths
.iter()
.map(|SortablePath(p)| p.as_slice())
.chain(
self.private_paths
.iter()
.map(|SortablePath(p)| p.as_slice()),
)
}
}
#[derive(
Debug,
Clone,
Eq,
PartialEq,
serde::Serialize,
serde::Deserialize,
bincode::Encode,
bincode::Decode,
)]
#[serde(transparent)]
pub struct SortablePath(pub Vec<String>);
impl Ord for SortablePath {
fn cmp(&self, other: &Self) -> Ordering {
match self.0.len().cmp(&other.0.len()) {
Ordering::Equal => self.0.cmp(&other.0),
other => other,
}
}
}
impl PartialOrd for SortablePath {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}