term_rustdoc/tree/nodes/
item_inner.rs1use super::{DEnum, DModule, DStruct, DTrait, DUnion};
2use crate::tree::{DocTree, IDMap, Show};
3use rustdoc_types::ItemEnum;
4
5#[derive(Debug, Clone, Copy)]
7pub enum DataItemKind {
8 Module,
9 Struct,
10 Enum,
11 Trait,
12 Union,
13}
14
15impl DataItemKind {
16 pub fn new(id: &str, map: &IDMap) -> Option<DataItemKind> {
17 map.get_item(id).and_then(|item| {
18 Some(match &item.inner {
19 ItemEnum::Module(_) => DataItemKind::Module,
20 ItemEnum::Struct(_) => DataItemKind::Struct,
21 ItemEnum::Enum(_) => DataItemKind::Enum,
22 ItemEnum::Trait(_) => DataItemKind::Trait,
23 ItemEnum::Union(_) => DataItemKind::Union,
24 ItemEnum::Import(reexport) => {
25 let id = reexport.id.as_ref().map(|id| &*id.0)?;
26 DataItemKind::new(id, map)?
27 }
28 _ => return None,
29 })
30 })
31 }
32}
33
34macro_rules! search {
35 () => {
36 search! {
37 search_for_struct structs DStruct,
38 search_for_enum enums DEnum,
39 search_for_trait traits DTrait,
40 search_for_union unions DUnion,
41 }
42 };
43 ($fname:ident $field:ident $typ:ident) => {
44 fn $fname<T>(
45 &self,
46 id: &str,
47 f: impl Copy + Fn(&$typ) -> T,
48 ) -> Option<T> {
49 for item in &self.$field {
50 if item.id.as_str() == id {
51 return Some(f(item));
52 }
53 }
54 for m in &self.modules {
55 let tree = m.$fname(id, f);
56 if tree.is_some() {
57 return tree;
58 }
59 }
60 None
61 }
62 };
63 ($($fname:ident $field:ident $typ:ident,)+) => {
64 impl DModule { $( search! { $fname $field $typ } )+ }
65 };
66}
67
68search! {}
69
70impl DModule {
72 fn search_for_module<T>(&self, id: &str, f: impl Copy + Fn(&DModule) -> T) -> Option<T> {
73 if self.id.as_str() == id {
74 return Some(f(self));
75 }
76 for m in &self.modules {
77 let tree = m.search_for_module(id, f);
78 if tree.is_some() {
79 return tree;
80 }
81 }
82 None
83 }
84
85 pub fn item_inner_tree(&self, id: &str, map: &IDMap) -> Option<DocTree> {
86 let kind = DataItemKind::new(id, map)?;
87 match kind {
88 DataItemKind::Struct => self.search_for_struct(id, |x| x.show_prettier(map)),
89 DataItemKind::Enum => self.search_for_enum(id, |x| x.show_prettier(map)),
90 DataItemKind::Trait => self.search_for_trait(id, |x| x.show_prettier(map)),
91 DataItemKind::Union => self.search_for_union(id, |x| x.show_prettier(map)),
92 DataItemKind::Module => self.search_for_module(id, |x| x.item_tree(map)),
93 }
94 }
95
96 pub fn impl_tree(&self, id: &str, map: &IDMap) -> Option<DocTree> {
97 let kind = DataItemKind::new(id, map)?;
98 match kind {
99 DataItemKind::Struct => self.search_for_struct(id, |x| x.impls.show_prettier(map)),
100 DataItemKind::Enum => self.search_for_enum(id, |x| x.impls.show_prettier(map)),
101 DataItemKind::Trait => self.search_for_trait(id, |x| x.show_prettier(map)),
102 DataItemKind::Union => self.search_for_union(id, |x| x.impls.show_prettier(map)),
103 _ => None,
104 }
105 }
106
107 pub fn implementor_tree(&self, id: &str, map: &IDMap) -> Option<DocTree> {
108 self.search_for_trait(id, |x| x.implementors(map))
109 }
110
111 pub fn associated_item_tree(&self, id: &str, map: &IDMap) -> Option<DocTree> {
112 self.search_for_trait(id, |x| x.associated_items(map))
113 }
114
115 pub fn field_tree(&self, id: &str, map: &IDMap) -> Option<DocTree> {
116 let kind = DataItemKind::new(id, map)?;
117 match kind {
118 DataItemKind::Struct => self.search_for_struct(id, |x| x.fields_tree(map)),
119 DataItemKind::Enum => self.search_for_enum(id, |x| x.variants_tree(map)),
120 DataItemKind::Union => self.search_for_union(id, |x| x.fields_tree(map)),
121 _ => None,
122 }
123 }
124}