term_rustdoc/tree/nodes/
traits.rs

1use crate::tree::{
2    impls::show::{show_ids, DocTree, Show},
3    IDMap, IDs, IdToID, SliceToIds, Tag, ID,
4};
5use rustdoc_types::{ItemEnum, Trait};
6
7#[derive(serde::Serialize, serde::Deserialize, Clone)]
8pub struct DTrait {
9    pub id: ID,
10    pub types: IDs,
11    pub constants: IDs,
12    pub functions: IDs,
13    pub implementations: IDs,
14}
15impl DTrait {
16    pub fn new(id: ID, item: &Trait, map: &IDMap) -> Self {
17        let [mut types, mut constants, mut functions]: [Vec<ID>; 3] = Default::default();
18        let trait_id = &id;
19        for id in &item.items {
20            let item_id = &*id.0;
21            if let Some(assoc) = map.get_item(item_id) {
22                let id = item_id.to_ID();
23                match &assoc.inner {
24                    ItemEnum::AssocType { .. } => types.push(id),
25                    ItemEnum::AssocConst { .. } => constants.push(id),
26                    ItemEnum::Function(_) => functions.push(id),
27                    _ => warn!(
28                        "`{}` ({item_id}) should refer to an associated item \
29                         (type/constant/function) in Trait `{}` ({trait_id})",
30                        map.name(item_id),
31                        map.name(trait_id)
32                    ),
33                }
34            } else {
35                warn!(
36                    "the trait item `{}` ({item_id:?}) not found in Crate's index",
37                    map.name(item_id)
38                );
39            }
40        }
41        types.sort_unstable_by_key(|id| map.name(id));
42        constants.sort_unstable_by_key(|id| map.name(id));
43        functions.sort_unstable_by_key(|id| map.name(id));
44        DTrait {
45            id,
46            types: types.into(),
47            constants: constants.into(),
48            functions: functions.into(),
49            implementations: item.implementations.to_ids(),
50        }
51    }
52
53    /// External items need external crates compiled to know details,
54    /// and the ID here is for PathMap, not IndexMap.
55    pub fn new_external(id: ID) -> Self {
56        let (types, constants, functions, implementations) = Default::default();
57        DTrait {
58            id,
59            types,
60            constants,
61            functions,
62            implementations,
63        }
64    }
65
66    pub fn associated_items(&self, map: &IDMap) -> DocTree {
67        let mut root = node!(Trait: map, &self.id);
68        names_node!(@iter self map root
69            constants AssocConst,
70            types     AssocType,
71            functions AssocFn,
72        );
73        root
74    }
75
76    pub fn implementors(&self, map: &IDMap) -> DocTree {
77        let mut root = node!(Trait: map, &self.id);
78        names_node!(@iter self map root
79            implementations Implementor,
80        );
81        root
82    }
83}
84
85impl Show for DTrait {
86    fn show(&self) -> DocTree {
87        format!("[trait] {}", self.id).show().with_leaves([
88            "Associated Constants"
89                .show()
90                .with_leaves(show_ids(&self.constants)),
91            "Associated Types".show().with_leaves(show_ids(&self.types)),
92            "Associated Functions"
93                .show()
94                .with_leaves(show_ids(&self.functions)),
95            "Implementors"
96                .show()
97                .with_leaves(show_ids(&self.implementations)),
98        ])
99    }
100
101    fn show_prettier(&self, map: &IDMap) -> DocTree {
102        let root = node!(Trait: map, &self.id);
103        let leaves = names_node!(
104            self map root.with_leaves([Tag::NoAssocOrImpls.show()]),
105            AssocConsts  constants AssocConst,
106            AssocTypes   types     AssocType,
107            AssocFns     functions AssocFn,
108            Implementors implementations Implementor,
109        );
110        root.with_leaves(leaves)
111    }
112}