use rustdoc_types::{Item, ItemEnum};
use crate::{public_item::PublicItemPath, render::RenderingContext, tokens::Token};
#[derive(Clone, Debug)]
pub struct NameableItem<'c> {
pub item: &'c Item,
pub overridden_name: Option<String>,
pub sorting_prefix: u8,
}
impl<'c> NameableItem<'c> {
pub fn name(&self) -> Option<&str> {
self.overridden_name
.as_deref()
.or(self.item.name.as_deref())
}
pub fn sortable_name(&self, context: &RenderingContext) -> String {
let mut sortable_name = format!("{:0>3}-", self.sorting_prefix);
if let Some(name) = self.name() {
sortable_name.push_str(name);
} else if let ItemEnum::Impl(impl_) = &self.item.inner {
sortable_name.push_str(&crate::tokens::tokens_to_string(
&context.render_impl(impl_, &[]),
));
if impl_.trait_.is_none() {
let mut assoc_item_names: Vec<&str> = impl_
.items
.iter()
.filter_map(|id| context.crate_.index.get(id))
.filter_map(|item| item.name.as_ref())
.map(String::as_str)
.collect();
assoc_item_names.sort_unstable();
sortable_name.push('-');
sortable_name.push_str(&assoc_item_names.join("-"));
}
}
sortable_name
}
}
#[derive(Clone, Debug)]
pub struct IntermediatePublicItem<'c> {
path: Vec<NameableItem<'c>>,
}
impl<'c> IntermediatePublicItem<'c> {
pub fn new(path: Vec<NameableItem<'c>>) -> Self {
Self { path }
}
#[must_use]
pub fn item(&self) -> &'c Item {
self.path().last().expect("path must not be empty").item
}
#[must_use]
pub fn path(&self) -> &[NameableItem<'c>] {
&self.path
}
#[must_use]
pub fn sortable_path(&self, context: &RenderingContext) -> PublicItemPath {
self.path()
.iter()
.map(|p| NameableItem::sortable_name(p, context))
.collect()
}
#[must_use]
pub fn path_contains_renamed_item(&self) -> bool {
self.path().iter().any(|m| m.overridden_name.is_some())
}
pub fn render_token_stream(&self, context: &RenderingContext) -> Vec<Token> {
context.token_stream(self)
}
}