1mod impls;
2pub use impls::{DImpl, DImplInner};
3
4mod structs;
5pub use structs::DStruct;
6
7mod unions;
8pub use unions::DUnion;
9
10mod enums;
11pub use enums::DEnum;
12
13mod traits;
14pub use traits::DTrait;
15
16mod imports;
17
18mod item_inner;
19pub use item_inner::DataItemKind;
20
21use super::IDMap;
22use crate::tree::{
23 impls::show::{DocTree, Show},
24 IdToID, ID,
25};
26use rustdoc_types::{Id, Item, ItemEnum, MacroKind, Module};
27use serde::{Deserialize, Serialize};
28use std::ops::Not;
29
30#[derive(Default, Serialize, Deserialize)]
35pub struct DModule {
36 pub id: ID,
37 pub modules: Vec<DModule>,
41 pub structs: Vec<DStruct>,
42 pub unions: Vec<DUnion>,
43 pub enums: Vec<DEnum>,
44 pub traits: Vec<DTrait>,
45 pub functions: Vec<DFunction>,
46 pub constants: Vec<DConstant>,
47 pub statics: Vec<DStatic>,
48 pub type_alias: Vec<DTypeAlias>,
49 pub macros_decl: Vec<DMacroDecl>,
50 pub macros_func: Vec<DMacroFunc>,
51 pub macros_attr: Vec<DMacroAttr>,
52 pub macros_derv: Vec<DMacroDerv>,
53}
54
55impl DModule {
56 pub fn new(map: &IDMap) -> Self {
57 let mut index = map.indexmap().iter();
59 let (id, root) = index
60 .find_map(|(id, item)| {
61 if item.crate_id == 0 {
62 if let ItemEnum::Module(Module {
63 is_crate: true,
64 items,
65 ..
66 }) = &item.inner
67 {
68 return Some((id.to_ID(), items.as_slice()));
69 }
70 }
71 None
72 })
73 .expect("root module not found");
74
75 let mut ancestor = Vec::with_capacity(8);
77
78 let mut dmod = Self::new_inner(id, root, map, &mut ancestor);
79 dmod.sort_by_name(map);
80 dmod
81 }
82
83 fn new_inner(id: ID, inner_items: &[Id], map: &IDMap, ancestor: &mut Vec<ID>) -> Self {
84 ancestor.push(id.clone());
85 debug!(
86 "Module Paths = {:?}",
87 ancestor.iter().map(|id| map.path(id)).collect::<Vec<_>>()
88 );
89 let mut dmod = DModule {
90 id,
91 ..Default::default()
92 };
93 dmod.extract_items(inner_items, map, ancestor);
94 dmod
95 }
96
97 fn new_external(id: ID) -> Self {
100 DModule {
101 id,
102 ..Default::default()
103 }
104 }
105
106 fn extract_items(&mut self, inner_items: &[Id], map: &IDMap, ancestor: &mut Vec<ID>) {
107 for item_id in inner_items {
108 match map.indexmap().get(item_id) {
109 Some(item) => self.append(item, map, ancestor),
110 None => warn!("the local item {item_id:?} not found in Crate's index"),
111 }
112 }
113 }
114
115 fn append(&mut self, item: &Item, map: &IDMap, ancestor: &mut Vec<ID>) {
116 use ItemEnum::*;
117 let id = item.id.to_ID();
118 match &item.inner {
119 Module(item) => {
120 let mut kin = ancestor.clone();
121 self.modules
122 .push(Self::new_inner(id, &item.items, map, &mut kin))
123 }
124 Struct(item) => self.structs.push(DStruct::new(id, item, map)),
125 Union(item) => self.unions.push(DUnion::new(id, item, map)),
126 Enum(item) => self.enums.push(DEnum::new(id, item, map)),
127 Trait(item) => self.traits.push(DTrait::new(id, item, map)),
128 Function(_) => self.functions.push(DFunction::new(id)),
129 Constant(_) => self.constants.push(DConstant::new(id)),
130 Static(_) => self.statics.push(DStatic::new(id)),
131 TypeAlias(_) => self.type_alias.push(DTypeAlias::new(id)),
132 Macro(_) => self.macros_decl.push(DMacroDecl::new(id)),
133 ProcMacro(proc) => match proc.kind {
134 MacroKind::Bang => self.macros_func.push(DMacroFunc::new(id)),
135 MacroKind::Attr => self.macros_attr.push(DMacroAttr::new(id)),
136 MacroKind::Derive => self.macros_derv.push(DMacroDerv::new(id)),
137 },
138 Import(import) => imports::parse_import(id, import, map, self, ancestor),
139 _ => (),
141 }
142 }
143}
144
145macro_rules! impl_show {
146 ($( $field:ident => $tag:ident => $node:ident => $fty:ident , )+ ) => {
147impl Show for DModule {
149 fn show(&self) -> DocTree {
150 format!("[mod] {}", self.id).show().with_leaves(
151 std::iter::empty()
152 $(
153 .chain( impl_show!(@show $field $node $fty self map) )
154 )+
155 .chain(self.modules.iter().map(DModule::show))
156 )
157 }
158
159 fn show_prettier(&self, map: &IDMap) -> DocTree {
160 node!(Module: map, &self.id).with_leaves(
161 std::iter::empty()
162 $(
163 .chain( impl_show!(@pretty $field $node self map) )
164 )+
165 .chain(self.modules.iter().map(|m| m.show_prettier(map)))
166 )
167 }
168}
169
170impl DModule {
171 pub fn item_tree(&self, map: &IDMap) -> DocTree {
173 node!(Module: map, &self.id).with_leaves(
174 std::iter::empty()
175 $(
176 .chain(self.$field.iter().map(|item| {
177 node!(@name $tag : map, &item.id)
178 }))
179 )+
180 .chain(self.modules.iter().map(|m| m.item_tree(map)))
181 )
182 }
183
184 fn sort_by_name(&mut self, map: &IDMap) {
186 self.modules.sort_unstable_by(|a, b| map.name(&a.id).cmp(&map.name(&b.id)));
187 self.modules.iter_mut().for_each(|m| m.sort_by_name(map));
188 $(self.$field.sort_unstable_by(|a, b| map.name(&a.id).cmp(&map.name(&b.id)));)+
189 }
190
191 pub fn item_tree_only_in_one_specified_mod(&self, map: &IDMap) -> DocTree {
193 node!(Module: map, &self.id).with_leaves(
194 std::iter::empty()
195 $(
196 .chain(self.$field.iter().map(|item| {
197 node!(@name $tag : map, &item.id)
198 }))
199 )+
200 )
201 }
202}
203 };
204 (@show $field:ident $node:ident $fty:ident $self:ident $map:ident) => {
205 $self.$field.is_empty().not().then(|| {
206 $crate::tree::Tag::$node.show().with_leaves($self.$field.iter().map($fty::show))
207 })
208 };
209 (@pretty $field:ident $node:ident $self:ident $map:ident) => {
210 $self.$field.is_empty().not().then(|| {
211 $crate::tree::Tag::$node.show().with_leaves($self.$field.iter().map(|val| val.show_prettier($map)))
212 })
213 };
214}
215
216impl_show! {
217 functions => Function => Functions => DFunction,
218 constants => Constant => Constants => DConstant,
219 statics => Static => Statics => DStatic,
220 type_alias => TypeAlias => TypeAliass => DTypeAlias,
221 macros_decl => MacroDecl => MacroDecls => DMacroDecl,
222 macros_func => MacroFunc => MacroFuncs => DMacroFunc,
223 macros_attr => MacroAttr => MacroAttrs => DMacroAttr,
224 macros_derv => MacroDerv => MacroDervs => DMacroDerv,
225 traits => Trait => Traits => DTrait,
226 structs => Struct => Structs => DStruct,
227 unions => Union => Unions => DUnion,
228 enums => Enum => Enums => DEnum,
229}
230
231macro_rules! gen_simple_items {
233 ($( $name:ident => $tag:ident => $kind:ident , )+ ) => {$(
234 #[derive(Debug, Serialize, Deserialize)] pub struct $name { pub id: ID, }
235 impl $name { pub fn new(id: ID) -> Self { Self { id } } }
236 impl Show for $name {
237 fn show(&self) -> DocTree { self.id.show() }
238 fn show_prettier(&self, map: &IDMap) -> DocTree {
239 node!(@name $tag: map, &self.id)
241 }
242 }
243 )+};
244}
245
246gen_simple_items! {
247 DFunction => Function => Function,
248 DConstant => Constant => Constant,
249 DStatic => Static => Static,
250 DTypeAlias => TypeAlias => TypeAlias,
251 DMacroDecl => MacroDecl => Macro,
252 DMacroFunc => MacroFunc => Macro,
253 DMacroAttr => MacroAttr => ProcAttribute,
254 DMacroDerv => MacroDerv => ProcDerive,
255}
256
257