@@ -7,11 +7,11 @@ use std::process::Command;
7
7
use anyhow:: Context ;
8
8
use rayon:: prelude:: * ;
9
9
10
- pub type Id = rustdoc_types:: Id ;
11
-
12
10
/// Write the analysis data to a subdirectory under target/ with this name.
13
11
const SUBDIR : & str = "rsbrowse" ;
14
12
13
+ const EMPTY_ID : & rustdoc_types:: Id = & rustdoc_types:: Id ( String :: new ( ) ) ;
14
+
15
15
pub struct Analysis {
16
16
pub crates : HashMap < String , rustdoc_types:: Crate > ,
17
17
}
@@ -86,93 +86,80 @@ impl Analysis {
86
86
Ok ( Self { crates } )
87
87
}
88
88
89
- pub fn crate_ids ( & self ) -> impl Iterator < Item = CrateId > + ' _ {
90
- /*let mut ids = vec![];
91
-
92
- for c in self.crates.values() {
93
- let name = c.index.iter()
94
- .find_map(|(_id, item)| {
95
- match &item.inner {
96
- rustdoc_types::ItemEnum::Module(m) if m.is_crate && item.crate_id == 0 => {
97
- Some(item.name.clone().expect("crate module should have a name"))
98
- }
99
- _ => None
100
- }
101
- })
102
- .expect("should have an index item for the local crate");
103
-
104
- ids.push(CrateId { name });
105
- }*/
106
-
89
+ pub fn crate_ids ( & self ) -> impl Iterator < Item = ItemId > + ' _ {
107
90
self . crates
108
91
. values ( )
109
92
. flat_map ( |crate_| & crate_. index )
110
93
. filter_map ( |( _id, item) | match & item. inner {
111
94
rustdoc_types:: ItemEnum :: Module ( m) if m. is_crate && item. crate_id == 0 => {
112
- let name = item. name . clone ( ) . expect ( "crate module should have a name" ) ;
113
- Some ( CrateId { name } )
95
+ let name = item. name . as_ref ( ) . expect ( "crate module should have a name" ) ;
96
+ Some ( ItemId :: crate_root ( CrateId { name } ) )
114
97
}
115
98
_ => None ,
116
99
} )
117
-
118
- //ids.into_iter()
119
100
}
120
101
121
102
pub fn items < ' a , ' b > (
122
103
& ' a self ,
123
- crate_id : & ' b CrateId ,
124
- parent_id : Option < Id > ,
125
- ) -> impl Iterator < Item = Item < ' a > > + ' b
104
+ parent_id : & ' b ItemId < ' a > ,
105
+ ) -> impl Iterator < Item = ( ItemId < ' a > , Item < ' a > ) > + ' b
126
106
where
127
107
' a : ' b ,
128
108
{
129
- let parent_id = parent_id. unwrap_or ( self . crates [ & crate_id. name ] . root . clone ( ) ) ;
130
- let parent = self
131
- . crates
132
- . get ( & crate_id. name )
133
- . unwrap_or_else ( || panic ! ( "no crate {crate_id:?}" ) )
134
- . index
135
- . get ( & parent_id)
136
- . unwrap_or_else ( || panic ! ( "no id {parent_id:?} in {crate_id:?}" ) ) ;
109
+ let ItemId ( parent_crate, parent_id) = parent_id;
110
+ let parent = {
111
+ let crate_ = & self
112
+ . crates
113
+ . get ( parent_crate. name )
114
+ . unwrap_or_else ( || panic ! ( "no crate {parent_crate:?}" ) ) ;
115
+ let id = if parent_id == & EMPTY_ID {
116
+ & crate_. root
117
+ } else {
118
+ parent_id
119
+ } ;
120
+ crate_
121
+ . index
122
+ . get ( id)
123
+ . unwrap_or_else ( || panic ! ( "no id {id:?} in {parent_crate:?}" ) )
124
+ } ;
137
125
138
126
use rustdoc_types:: ItemEnum :: * ;
139
- let children = match & parent. inner {
140
- Module ( m) => m. items . clone ( ) ,
127
+ let children: Vec < & ' a rustdoc_types :: Id > = match & parent. inner {
128
+ Module ( m) => m. items . iter ( ) . collect ( ) ,
141
129
ExternCrate { .. } => vec ! [ ] ,
142
130
Import ( _) => vec ! [ ] ,
143
- Union ( u) => [ & u. fields [ .. ] , & u. impls [ .. ] ] . concat ( ) ,
131
+ Union ( u) => u. fields . iter ( ) . chain ( & u. impls ) . collect ( ) ,
144
132
Struct ( s) => {
145
133
let fields = match & s. kind {
146
134
rustdoc_types:: StructKind :: Unit => vec ! [ ] ,
147
135
rustdoc_types:: StructKind :: Tuple ( t) => {
148
- t. iter ( ) . filter_map ( |x| x. as_ref ( ) ) . cloned ( ) . collect ( )
136
+ t. iter ( ) . filter_map ( |x| x. as_ref ( ) ) . collect ( )
149
137
}
150
- rustdoc_types:: StructKind :: Plain { fields, .. } => fields. clone ( ) ,
138
+ rustdoc_types:: StructKind :: Plain { fields, .. } => fields. iter ( ) . collect ( ) ,
151
139
} ;
152
- [ & fields[ .. ] , & s. impls [ .. ] ] . concat ( )
140
+ fields. into_iter ( ) . chain ( & s. impls ) . collect ( )
153
141
}
154
142
StructField ( ty) => type_ids ( ty) ,
155
- Enum ( e) => [ & e. variants [ .. ] , & e. impls [ .. ] ] . concat ( ) ,
143
+ Enum ( e) => e. variants . iter ( ) . chain ( & e. impls ) . collect ( ) ,
156
144
Variant ( v) => match & v. kind {
157
145
rustdoc_types:: VariantKind :: Plain => vec ! [ ] ,
158
146
rustdoc_types:: VariantKind :: Tuple ( t) => {
159
- t. iter ( ) . filter_map ( |id| id. clone ( ) ) . collect ( )
147
+ t. iter ( ) . filter_map ( |id| id. as_ref ( ) ) . collect ( )
160
148
}
161
- rustdoc_types:: VariantKind :: Struct { fields, .. } => fields. clone ( ) ,
149
+ rustdoc_types:: VariantKind :: Struct { fields, .. } => fields. iter ( ) . collect ( ) ,
162
150
} ,
163
151
Function ( _) => vec ! [ ] ,
164
152
Trait ( t) => {
165
153
// TODO: also find impls?
166
- t. items . clone ( )
154
+ t. items . iter ( ) . collect ( )
167
155
}
168
156
TraitAlias ( _) => vec ! [ ] ,
169
157
Impl ( i) => {
170
- let mut items = i. items . clone ( ) ;
171
- // Add a reference to the trait itself too if it's not an inherent impl:
172
- if let Some ( trait_) = & i. trait_ {
173
- items. push ( trait_. id . clone ( ) ) ;
174
- }
175
- items
158
+ i. items
159
+ . iter ( )
160
+ // Add a reference to the trait itself too if it's not an inherent impl:
161
+ . chain ( i. trait_ . as_ref ( ) . map ( |t| & t. id ) )
162
+ . collect ( )
176
163
}
177
164
TypeAlias ( ty) => type_ids ( & ty. type_ ) ,
178
165
OpaqueTy ( _) => vec ! [ ] ,
@@ -187,10 +174,18 @@ impl Analysis {
187
174
} ;
188
175
189
176
children. into_iter ( ) . filter_map ( move |id| {
190
- if let Some ( item) = self . crates [ & crate_id. name ] . index . get ( & id) {
191
- Some ( Item :: Item ( item) )
177
+ if let Some ( item) = self . crates [ parent_crate. name ] . index . get ( id) {
178
+ Some ( (
179
+ ItemId (
180
+ CrateId {
181
+ name : parent_crate. name ,
182
+ } ,
183
+ id,
184
+ ) ,
185
+ Item :: Item ( item) ,
186
+ ) )
192
187
} else {
193
- let summary = self . crates [ & crate_id . name ] . paths . get ( & id) ?;
188
+ let summary = self . crates [ parent_crate . name ] . paths . get ( id) ?;
194
189
let other_crate = & summary. path [ 0 ] ;
195
190
let other_id =
196
191
self . crates
@@ -205,11 +200,9 @@ impl Analysis {
205
200
}
206
201
} ) ?;
207
202
let item = self . crates [ other_crate] . index . get ( other_id) ?;
208
- Some ( Item :: Foreign (
209
- CrateId {
210
- name : other_crate. to_owned ( ) ,
211
- } ,
212
- item,
203
+ Some ( (
204
+ ItemId ( CrateId { name : other_crate } , other_id) ,
205
+ Item :: Item ( item) ,
213
206
) )
214
207
}
215
208
} )
@@ -222,11 +215,11 @@ fn parse_json(p: &Path) -> anyhow::Result<rustdoc_types::Crate> {
222
215
Ok ( data)
223
216
}
224
217
225
- fn type_ids ( ty : & rustdoc_types:: Type ) -> Vec < Id > {
218
+ fn type_ids ( ty : & rustdoc_types:: Type ) -> Vec < & rustdoc_types :: Id > {
226
219
use rustdoc_types:: Type :: * ;
227
220
match ty {
228
- ResolvedPath ( path) => vec ! [ path. id. clone ( ) ] ,
229
- DynTrait ( dt) => dt. traits . iter ( ) . map ( |t| t. trait_ . id . clone ( ) ) . collect ( ) ,
221
+ ResolvedPath ( path) => vec ! [ & path. id] ,
222
+ DynTrait ( dt) => dt. traits . iter ( ) . map ( |t| & t. trait_ . id ) . collect ( ) ,
230
223
Generic ( _) => vec ! [ ] ,
231
224
Primitive ( _) => vec ! [ ] ,
232
225
FunctionPointer ( _) => vec ! [ ] ,
@@ -236,7 +229,7 @@ fn type_ids(ty: &rustdoc_types::Type) -> Vec<Id> {
236
229
ImplTrait ( generics) => generics
237
230
. iter ( )
238
231
. filter_map ( |g| match g {
239
- rustdoc_types:: GenericBound :: TraitBound { trait_, .. } => Some ( trait_. id . clone ( ) ) ,
232
+ rustdoc_types:: GenericBound :: TraitBound { trait_, .. } => Some ( & trait_. id ) ,
240
233
rustdoc_types:: GenericBound :: Outlives ( _) => None ,
241
234
} )
242
235
. collect ( ) ,
@@ -248,7 +241,7 @@ fn type_ids(ty: &rustdoc_types::Type) -> Vec<Id> {
248
241
} => {
249
242
let from_self = type_ids ( self_type) ;
250
243
if let Some ( t) = trait_ {
251
- [ & from_self[ ..] , & [ t. id . clone ( ) ] ] . concat ( )
244
+ [ & from_self[ ..] , & [ & t. id ] ] . concat ( )
252
245
} else {
253
246
from_self
254
247
}
@@ -257,17 +250,28 @@ fn type_ids(ty: &rustdoc_types::Type) -> Vec<Id> {
257
250
}
258
251
259
252
#[ derive( Debug , Clone ) ]
260
- pub struct CrateId {
261
- pub name : String ,
262
- //pub id: u32,
253
+ pub struct CrateId < ' a > {
254
+ pub name : & ' a String ,
255
+ }
256
+
257
+ #[ derive( Debug , Clone ) ]
258
+ pub struct ItemId < ' a > ( CrateId < ' a > , & ' a rustdoc_types:: Id ) ;
259
+
260
+ impl < ' a > ItemId < ' a > {
261
+ pub fn crate_root ( crate_id : CrateId < ' a > ) -> Self {
262
+ Self ( crate_id, EMPTY_ID )
263
+ }
264
+
265
+ pub fn crate_name ( & self ) -> & str {
266
+ self . 0 . name
267
+ }
263
268
}
264
269
265
270
#[ allow( clippy:: large_enum_variant) ]
266
271
#[ derive( Debug , Clone ) ]
267
272
pub enum Item < ' a > {
268
273
Root ,
269
274
Item ( & ' a rustdoc_types:: Item ) ,
270
- Foreign ( CrateId , & ' a rustdoc_types:: Item ) ,
271
275
}
272
276
273
277
#[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
0 commit comments