1pub mod format;
2
3use std::io::Write;
4use std::ops::Deref;
5use std::path::Path;
6
7use rustdoc_json::Color;
8use rustdoc_types::{Id, Type};
9
10pub trait CrateItem<'a> {
11 type Inner;
12 fn downcast(inner: &'a rustdoc_types::ItemEnum) -> Option<&'a Self::Inner>;
13 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, inner: &'a Self::Inner) -> Self;
14 fn krate(&self) -> &'a Crate;
15 fn item(&self) -> &'a rustdoc_types::Item;
16 fn inner(&self) -> &'a Self::Inner;
17 fn is_public(&self) -> bool {
18 self.item().visibility == rustdoc_types::Visibility::Public
19 }
20 fn is_crate_item(&self) -> bool {
21 self.item().crate_id == 0
22 }
23 fn is_root_item(&self) -> bool {
24 self.module()
25 .is_some_and(|module| module.id() == &self.krate().root)
26 }
27 fn is_external_item(&self) -> bool {
28 self.item().crate_id != 0
29 }
30 fn id(&'a self) -> &'a Id {
31 &self.item().id
32 }
33 fn module(&self) -> Option<ModuleItem<'a>> {
34 self.krate()
35 .all_modules()
36 .find(|module| module.module.items.contains(&self.item().id))
37 }
38}
39
40pub trait HasType {
41 fn type_(&self) -> &Type;
42}
43
44pub trait HasName {
45 fn name(&self) -> &str;
46}
47
48macro_rules! impl_items {
49 ($ty: ident < $l: lifetime >) => {
50 impl<$l> $ty<$l> {
51 pub fn constants(&self) -> impl Iterator<Item = ConstantItem<'_>> {
52 self.items()
53 .filter_map(|item| self.krate().downcast::<ConstantItem>(item))
54 }
55
56 pub fn functions(&self) -> impl Iterator<Item = FunctionItem<'_>> {
57 self.items()
58 .filter_map(|item| self.krate().downcast::<FunctionItem>(item))
59 }
60
61 pub fn structs(&self) -> impl Iterator<Item = StructItem<'_>> {
62 self.items()
63 .filter_map(|item| self.krate().downcast::<StructItem>(item))
64 }
65
66 pub fn enums(&self) -> impl Iterator<Item = EnumItem<'_>> {
67 self.items()
68 .filter_map(|item| self.krate().downcast::<EnumItem>(item))
69 }
70
71 pub fn traits(&self) -> impl Iterator<Item = TraitItem<'_>> {
72 self.items()
73 .filter_map(|item| self.krate().downcast::<TraitItem>(item))
74 }
75
76 pub fn type_aliases(&self) -> impl Iterator<Item = TypeAliasItem<'_>> {
77 self.items()
78 .filter_map(|item| self.krate().downcast::<TypeAliasItem>(item))
79 }
80
81 pub fn trait_aliases(&self) -> impl Iterator<Item = TraitAliasItem<'_>> {
82 self.items()
83 .filter_map(|item| self.krate().downcast::<TraitAliasItem>(item))
84 }
85
86 pub fn unions(&self) -> impl Iterator<Item = UnionItem<'_>> {
87 self.items()
88 .filter_map(|item| self.krate().downcast::<UnionItem>(item))
89 }
90
91 pub fn modules(&self) -> impl Iterator<Item = ModuleItem<'_>> {
92 self.items()
93 .filter_map(|item| self.krate().downcast::<ModuleItem>(item))
94 }
95
96 pub fn impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
97 self.items()
98 .filter_map(|item| self.krate().downcast::<ImplItem>(item))
99 }
100
101 pub fn uses(&self) -> impl Iterator<Item = UseItem<'_>> {
102 self.items()
103 .filter_map(|item| self.krate().downcast::<UseItem>(item))
104 }
105
106 pub fn get_item(&self, name: &str) -> Option<&rustdoc_types::Item> {
108 self.items()
109 .find(|item| item.name.as_ref().is_some_and(|n| n == name))
110 }
111
112 pub fn get_constant(&self, name: &str) -> Option<ConstantItem<'_>> {
114 self.constants().find(|constant| constant.name() == name)
115 }
116
117 pub fn get_function(&self, name: &str) -> Option<FunctionItem<'_>> {
119 self.functions().find(|func| func.name() == name)
120 }
121
122 pub fn get_struct(&self, name: &str) -> Option<StructItem<'_>> {
124 self.structs().find(|struct_| struct_.name() == name)
125 }
126
127 pub fn get_enum(&self, name: &str) -> Option<EnumItem<'_>> {
129 self.enums().find(|enum_| enum_.name() == name)
130 }
131
132 pub fn get_trait(&self, name: &str) -> Option<TraitItem<'_>> {
134 self.traits().find(|trait_| trait_.name() == name)
135 }
136
137 pub fn get_type_alias(&self, name: &str) -> Option<TypeAliasItem<'_>> {
139 self.type_aliases()
140 .find(|type_alias| type_alias.name() == name)
141 }
142
143 pub fn get_trait_alias(&self, name: &str) -> Option<TraitAliasItem<'_>> {
145 self.trait_aliases()
146 .find(|trait_alias| trait_alias.name() == name)
147 }
148
149 pub fn get_union(&self, name: &str) -> Option<UnionItem<'_>> {
151 self.unions().find(|union| union.name() == name)
152 }
153
154 pub fn get_module(&self, name: &str) -> Option<ModuleItem<'_>> {
156 self.modules().find(|module| module.name() == name)
157 }
158 }
159 };
160}
161
162#[derive(Debug, Copy, Clone, PartialEq, Eq)]
163pub struct ModuleItem<'a> {
164 krate: &'a Crate,
165 item: &'a rustdoc_types::Item,
166 module: &'a rustdoc_types::Module,
167}
168
169impl<'a> CrateItem<'a> for ModuleItem<'a> {
170 type Inner = rustdoc_types::Module;
171 fn downcast(inner: &'a rustdoc_types::ItemEnum) -> Option<&'a Self::Inner> {
172 match inner {
173 rustdoc_types::ItemEnum::Module(module) => Some(module),
174 _ => None,
175 }
176 }
177 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, module: &'a Self::Inner) -> Self {
178 Self {
179 krate,
180 item,
181 module,
182 }
183 }
184 fn item(&self) -> &'a rustdoc_types::Item {
185 self.item
186 }
187 fn inner(&self) -> &'a Self::Inner {
188 self.module
189 }
190 fn krate(&self) -> &'a Crate {
191 self.krate
192 }
193}
194
195impl HasName for ModuleItem<'_> {
196 fn name(&self) -> &str {
197 self.item.name.as_ref().unwrap()
198 }
199}
200
201impl<'a> ModuleItem<'a> {
202 pub fn name(&self) -> &str {
203 self.item.name.as_ref().unwrap()
204 }
205
206 pub fn item_ids(&self) -> impl Iterator<Item = &Id> {
207 self.module.items.iter()
208 }
209
210 pub fn items(&self) -> impl Iterator<Item = &rustdoc_types::Item> {
211 self.item_ids().map(|id| &self.krate.index[id])
212 }
213
214 pub fn parent(&self) -> Option<ModuleItem<'a>> {
215 self.krate
216 .all_modules()
217 .find(|module| module.module.items.contains(&self.item.id))
218 }
219
220 pub fn is_crate(&self) -> bool {
221 self.module.is_crate
222 }
223
224 pub fn is_stripped(&self) -> bool {
225 self.module.is_stripped
226 }
227}
228
229impl_items!(ModuleItem<'a>);
230
231#[derive(Debug, Copy, Clone, PartialEq, Eq)]
232pub struct FunctionItem<'a> {
233 krate: &'a Crate,
234 item: &'a rustdoc_types::Item,
235 func: &'a rustdoc_types::Function,
236}
237
238impl<'a> CrateItem<'a> for FunctionItem<'a> {
239 type Inner = rustdoc_types::Function;
240 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
241 match inner {
242 rustdoc_types::ItemEnum::Function(func) => Some(func),
243 _ => None,
244 }
245 }
246 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, func: &'a Self::Inner) -> Self {
247 Self { krate, item, func }
248 }
249 fn item(&self) -> &'a rustdoc_types::Item {
250 self.item
251 }
252 fn inner(&self) -> &'a Self::Inner {
253 self.func
254 }
255 fn krate(&self) -> &'a Crate {
256 self.krate
257 }
258}
259
260impl HasName for FunctionItem<'_> {
261 fn name(&self) -> &str {
262 self.item.name.as_ref().unwrap()
263 }
264}
265
266impl<'a> FunctionItem<'a> {
267 pub fn name(&self) -> &str {
268 self.item.name.as_ref().unwrap()
269 }
270
271 pub fn is_method(&self) -> bool {
272 self.func
273 .sig
274 .inputs
275 .first()
276 .is_some_and(|(name, _)| name == "self")
277 }
278
279 pub fn is_associated(&self) -> bool {
280 self.krate
281 .all_impls()
282 .any(|imp| imp.item_ids().any(|id| id == &self.item.id))
283 }
284
285 pub fn associated_impl(&self) -> Option<ImplItem<'a>> {
286 self.krate
287 .all_impls()
288 .find(|imp| imp.item_ids().any(|id| id == &self.item.id))
289 }
290
291 pub fn inputs(&self) -> impl Iterator<Item = &(String, Type)> {
292 self.func.sig.inputs.iter()
293 }
294
295 pub fn output(&self) -> Option<&Type> {
296 self.func.sig.output.as_ref()
297 }
298
299 pub fn sig(&self) -> &rustdoc_types::FunctionSignature {
300 &self.func.sig
301 }
302
303 pub fn generics(&self) -> &rustdoc_types::Generics {
304 &self.func.generics
305 }
306
307 pub fn header(&self) -> &rustdoc_types::FunctionHeader {
308 &self.func.header
309 }
310
311 pub fn has_body(&self) -> bool {
312 self.func.has_body
313 }
314}
315
316#[derive(Debug, Copy, Clone, PartialEq, Eq)]
317pub struct ConstantItem<'a> {
318 krate: &'a Crate,
319 item: &'a rustdoc_types::Item,
320 constant_item: &'a rustdoc_types::ItemEnum,
321}
322
323impl<'a> CrateItem<'a> for ConstantItem<'a> {
324 type Inner = rustdoc_types::ItemEnum;
325 fn downcast(inner: &'a rustdoc_types::ItemEnum) -> Option<&'a Self::Inner> {
326 match inner {
327 rustdoc_types::ItemEnum::Constant { .. } => Some(inner),
328 _ => None,
329 }
330 }
331 fn new(
332 krate: &'a Crate,
333 item: &'a rustdoc_types::Item,
334 constant_item: &'a Self::Inner,
335 ) -> Self {
336 Self {
337 krate,
338 item,
339 constant_item,
340 }
341 }
342 fn item(&self) -> &'a rustdoc_types::Item {
343 self.item
344 }
345 fn inner(&self) -> &'a Self::Inner {
346 self.constant_item
347 }
348 fn krate(&self) -> &'a Crate {
349 self.krate
350 }
351}
352
353impl HasName for ConstantItem<'_> {
354 fn name(&self) -> &str {
355 self.item.name.as_ref().unwrap()
356 }
357}
358
359impl HasType for ConstantItem<'_> {
360 fn type_(&self) -> &Type {
361 let rustdoc_types::ItemEnum::Constant { type_, .. } = &self.constant_item else {
362 unreachable!();
363 };
364 type_
365 }
366}
367
368impl<'a> ConstantItem<'a> {
369 pub fn name(&self) -> &str {
370 self.item.name.as_ref().unwrap()
371 }
372
373 pub fn type_(&self) -> &Type {
374 let rustdoc_types::ItemEnum::Constant { type_, .. } = &self.constant_item else {
375 unreachable!();
376 };
377 type_
378 }
379
380 pub fn expr(&self) -> &str {
381 let rustdoc_types::ItemEnum::Constant { const_, .. } = &self.constant_item else {
382 unreachable!();
383 };
384 &const_.expr
385 }
386
387 pub fn value(&self) -> Option<&str> {
388 let rustdoc_types::ItemEnum::Constant { const_, .. } = &self.constant_item else {
389 unreachable!();
390 };
391 const_.value.as_deref()
392 }
393}
394
395#[derive(Debug, Copy, Clone, PartialEq, Eq)]
396pub struct StaticItem<'a> {
397 krate: &'a Crate,
398 item: &'a rustdoc_types::Item,
399 static_: &'a rustdoc_types::Static,
400}
401
402impl<'a> CrateItem<'a> for StaticItem<'a> {
403 type Inner = rustdoc_types::Static;
404 fn downcast(inner: &'a rustdoc_types::ItemEnum) -> Option<&'a Self::Inner> {
405 match inner {
406 rustdoc_types::ItemEnum::Static(static_) => Some(static_),
407 _ => None,
408 }
409 }
410 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, static_: &'a Self::Inner) -> Self {
411 Self {
412 krate,
413 item,
414 static_,
415 }
416 }
417 fn item(&self) -> &'a rustdoc_types::Item {
418 self.item
419 }
420 fn inner(&self) -> &'a Self::Inner {
421 self.static_
422 }
423 fn krate(&self) -> &'a Crate {
424 self.krate
425 }
426}
427
428impl HasName for StaticItem<'_> {
429 fn name(&self) -> &str {
430 self.item.name.as_ref().unwrap()
431 }
432}
433
434impl HasType for StaticItem<'_> {
435 fn type_(&self) -> &Type {
436 &self.static_.type_
437 }
438}
439
440impl<'a> StaticItem<'a> {
441 pub fn name(&self) -> &str {
442 self.item.name.as_ref().unwrap()
443 }
444
445 pub fn type_(&self) -> &Type {
446 &self.static_.type_
447 }
448
449 pub fn expr(&self) -> &str {
450 &self.static_.expr
451 }
452
453 pub fn is_mutable(&self) -> bool {
454 self.static_.is_mutable
455 }
456
457 pub fn is_unsafe(&self) -> bool {
458 self.static_.is_unsafe
459 }
460}
461
462#[derive(Debug, Copy, Clone, PartialEq, Eq)]
463pub struct StructItem<'a> {
464 krate: &'a Crate,
465 item: &'a rustdoc_types::Item,
466 struct_: &'a rustdoc_types::Struct,
467}
468
469impl<'a> CrateItem<'a> for StructItem<'a> {
470 type Inner = rustdoc_types::Struct;
471 fn downcast(inner: &'a rustdoc_types::ItemEnum) -> Option<&'a Self::Inner> {
472 match inner {
473 rustdoc_types::ItemEnum::Struct(struct_) => Some(struct_),
474 _ => None,
475 }
476 }
477 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, struct_: &'a Self::Inner) -> Self {
478 Self {
479 krate,
480 item,
481 struct_,
482 }
483 }
484 fn item(&self) -> &'a rustdoc_types::Item {
485 self.item
486 }
487 fn inner(&self) -> &'a Self::Inner {
488 self.struct_
489 }
490 fn krate(&self) -> &'a Crate {
491 self.krate
492 }
493}
494
495impl HasName for StructItem<'_> {
496 fn name(&self) -> &str {
497 self.item.name.as_ref().unwrap()
498 }
499}
500
501impl<'a> StructItem<'a> {
502 pub fn name(&self) -> &str {
503 self.item.name.as_ref().unwrap()
504 }
505
506 pub fn field_ids(&self) -> Option<impl Iterator<Item = &Id>> {
507 match &self.struct_.kind {
508 rustdoc_types::StructKind::Unit => None,
509 rustdoc_types::StructKind::Tuple(_) => None,
510 rustdoc_types::StructKind::Plain { fields, .. } => Some(fields.iter()),
511 }
512 }
513
514 pub fn fields(&self) -> Option<impl Iterator<Item = FieldItem<'_>>> {
515 self.field_ids().map(|ids| {
516 ids.map(|id| {
517 let item = &self.krate.index[id];
518 let rustdoc_types::ItemEnum::StructField(field) = &item.inner else {
519 panic!("expected struct field, got {:?}", item.inner);
520 };
521 FieldItem {
522 krate: self.krate,
523 item,
524 field,
525 }
526 })
527 })
528 }
529
530 pub fn impl_ids(&self) -> impl Iterator<Item = &Id> {
531 self.struct_.impls.iter()
532 }
533
534 pub fn impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
535 self.impl_ids().map(|id| {
536 let item = &self.krate.index[id];
537 let rustdoc_types::ItemEnum::Impl(imp) = &item.inner else {
538 panic!("expected impl, got {:?}", item.inner);
539 };
540 ImplItem {
541 krate: self.krate,
542 item,
543 impl_: imp,
544 }
545 })
546 }
547
548 pub fn trait_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
551 self.impls().filter(|imp| imp.trait_().is_some())
552 }
553
554 pub fn blanket_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
556 self.trait_impls()
557 .filter(|imp| imp.impl_.blanket_impl.is_some())
558 }
559
560 pub fn non_blanket_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
562 self.trait_impls()
563 .filter(|imp| imp.impl_.blanket_impl.is_none())
564 }
565
566 pub fn associated_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
568 self.impls().filter(|imp| imp.trait_().is_none())
569 }
570
571 pub fn kind(&self) -> &rustdoc_types::StructKind {
572 &self.struct_.kind
573 }
574
575 pub fn generics(&self) -> &rustdoc_types::Generics {
576 &self.struct_.generics
577 }
578}
579
580#[derive(Debug, Copy, Clone, PartialEq, Eq)]
581pub struct FieldItem<'a> {
582 krate: &'a Crate,
583 item: &'a rustdoc_types::Item,
584 field: &'a rustdoc_types::Type,
585}
586
587impl<'a> CrateItem<'a> for FieldItem<'a> {
588 type Inner = rustdoc_types::Type;
589 fn downcast(inner: &'a rustdoc_types::ItemEnum) -> Option<&'a Self::Inner> {
590 match inner {
591 rustdoc_types::ItemEnum::StructField(field) => Some(field),
592 _ => None,
593 }
594 }
595 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, field: &'a Self::Inner) -> Self {
596 Self { krate, item, field }
597 }
598 fn item(&self) -> &'a rustdoc_types::Item {
599 self.item
600 }
601 fn inner(&self) -> &'a Self::Inner {
602 self.field
603 }
604 fn krate(&self) -> &'a Crate {
605 self.krate
606 }
607}
608
609impl<'a> HasType for FieldItem<'a> {
610 fn type_(&self) -> &Type {
611 self.field
612 }
613}
614
615impl HasName for FieldItem<'_> {
616 fn name(&self) -> &str {
617 self.item.name.as_ref().unwrap()
618 }
619}
620
621impl<'a> FieldItem<'a> {
622 pub fn name(&self) -> &str {
623 self.item.name.as_ref().unwrap()
624 }
625
626 pub fn type_(&self) -> &Type {
627 self.field
628 }
629}
630
631#[derive(Debug, Copy, Clone, PartialEq, Eq)]
632pub struct TraitItem<'a> {
633 krate: &'a Crate,
634 item: &'a rustdoc_types::Item,
635 trait_: &'a rustdoc_types::Trait,
636}
637
638impl<'a> CrateItem<'a> for TraitItem<'a> {
639 type Inner = rustdoc_types::Trait;
640 fn downcast(inner: &'a rustdoc_types::ItemEnum) -> Option<&'a Self::Inner> {
641 match inner {
642 rustdoc_types::ItemEnum::Trait(trait_) => Some(trait_),
643 _ => None,
644 }
645 }
646 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, trait_: &'a Self::Inner) -> Self {
647 Self {
648 krate,
649 item,
650 trait_,
651 }
652 }
653 fn item(&self) -> &'a rustdoc_types::Item {
654 self.item
655 }
656 fn inner(&self) -> &'a Self::Inner {
657 self.trait_
658 }
659 fn krate(&self) -> &'a Crate {
660 self.krate
661 }
662}
663
664impl HasName for TraitItem<'_> {
665 fn name(&self) -> &str {
666 self.item.name.as_ref().unwrap()
667 }
668}
669
670impl<'a> TraitItem<'a> {
671 pub fn name(&self) -> &str {
672 self.item.name.as_ref().unwrap()
673 }
674
675 pub fn item_ids(&self) -> impl Iterator<Item = &Id> {
676 self.trait_.items.iter()
677 }
678
679 pub fn items(&self) -> impl Iterator<Item = &rustdoc_types::Item> {
680 self.item_ids().map(|id| &self.krate.index[id])
681 }
682
683 pub fn impl_ids(&self) -> impl Iterator<Item = &Id> {
684 self.trait_.implementations.iter()
685 }
686
687 pub fn impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
688 self.impl_ids().map(|id| {
689 let item = &self.krate.index[id];
690 let rustdoc_types::ItemEnum::Impl(imp) = &item.inner else {
691 panic!("expected impl, got {:?}", item.inner);
692 };
693 ImplItem {
694 krate: self.krate,
695 item,
696 impl_: imp,
697 }
698 })
699 }
700
701 pub fn generics(&self) -> &rustdoc_types::Generics {
702 &self.trait_.generics
703 }
704
705 pub fn bounds(&self) -> &[rustdoc_types::GenericBound] {
706 &self.trait_.bounds
707 }
708
709 pub fn is_auto(&self) -> bool {
710 self.trait_.is_auto
711 }
712
713 pub fn is_unsafe(&self) -> bool {
714 self.trait_.is_unsafe
715 }
716
717 pub fn is_dyn_compatible(&self) -> bool {
718 self.trait_.is_dyn_compatible
719 }
720}
721
722#[derive(Debug, Copy, Clone, PartialEq, Eq)]
723pub struct EnumItem<'a> {
724 krate: &'a Crate,
725 item: &'a rustdoc_types::Item,
726 enum_: &'a rustdoc_types::Enum,
727}
728
729impl<'a> CrateItem<'a> for EnumItem<'a> {
730 type Inner = rustdoc_types::Enum;
731 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
732 match inner {
733 rustdoc_types::ItemEnum::Enum(enum_) => Some(enum_),
734 _ => None,
735 }
736 }
737 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, enum_: &'a Self::Inner) -> Self {
738 Self { krate, item, enum_ }
739 }
740 fn item(&self) -> &'a rustdoc_types::Item {
741 self.item
742 }
743 fn inner(&self) -> &'a Self::Inner {
744 self.enum_
745 }
746 fn krate(&self) -> &'a Crate {
747 self.krate
748 }
749}
750
751impl HasName for EnumItem<'_> {
752 fn name(&self) -> &str {
753 self.item.name.as_ref().unwrap()
754 }
755}
756
757impl<'a> EnumItem<'a> {
758 pub fn name(&self) -> &str {
759 self.item.name.as_ref().unwrap()
760 }
761
762 pub fn variant_ids(&self) -> impl Iterator<Item = &Id> {
763 self.enum_.variants.iter()
764 }
765
766 pub fn variants(&self) -> impl Iterator<Item = VariantItem<'_>> {
767 self.variant_ids().map(|id| {
768 let item = &self.krate.index[id];
769 let rustdoc_types::ItemEnum::Variant(variant) = &item.inner else {
770 panic!("expected variant, got {:?}", item.inner);
771 };
772 VariantItem {
773 krate: self.krate,
774 item,
775 variant,
776 }
777 })
778 }
779
780 pub fn impl_ids(&self) -> impl Iterator<Item = &Id> {
781 self.enum_.impls.iter()
782 }
783
784 pub fn impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
785 self.impl_ids().map(|id| {
786 let item = &self.krate.index[id];
787 let rustdoc_types::ItemEnum::Impl(imp) = &item.inner else {
788 panic!("expected impl, got {:?}", item.inner);
789 };
790 ImplItem {
791 krate: self.krate,
792 item,
793 impl_: imp,
794 }
795 })
796 }
797
798 pub fn trait_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
799 self.impls().filter(|imp| imp.trait_().is_some())
800 }
801
802 pub fn blanket_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
803 self.trait_impls()
804 .filter(|imp| imp.impl_.blanket_impl.is_some())
805 }
806
807 pub fn non_blanket_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
808 self.trait_impls()
809 .filter(|imp| imp.impl_.blanket_impl.is_none())
810 }
811
812 pub fn associated_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
814 self.impls().filter(|imp| imp.trait_().is_none())
815 }
816
817 pub fn generics(&self) -> &rustdoc_types::Generics {
818 &self.enum_.generics
819 }
820
821 pub fn has_stripped_variants(&self) -> bool {
822 self.enum_.has_stripped_variants
823 }
824}
825
826#[derive(Debug, Copy, Clone, PartialEq, Eq)]
827pub struct VariantItem<'a> {
828 krate: &'a Crate,
829 item: &'a rustdoc_types::Item,
830 variant: &'a rustdoc_types::Variant,
831}
832
833impl<'a> CrateItem<'a> for VariantItem<'a> {
834 type Inner = rustdoc_types::Variant;
835 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
836 match inner {
837 rustdoc_types::ItemEnum::Variant(variant) => Some(variant),
838 _ => None,
839 }
840 }
841 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, variant: &'a Self::Inner) -> Self {
842 Self {
843 krate,
844 item,
845 variant,
846 }
847 }
848 fn item(&self) -> &'a rustdoc_types::Item {
849 self.item
850 }
851 fn inner(&self) -> &'a Self::Inner {
852 self.variant
853 }
854 fn krate(&self) -> &'a Crate {
855 self.krate
856 }
857}
858
859impl HasName for VariantItem<'_> {
860 fn name(&self) -> &str {
861 self.item.name.as_ref().unwrap()
862 }
863}
864
865impl<'a> VariantItem<'a> {
866 pub fn name(&self) -> &str {
867 self.item.name.as_ref().unwrap()
868 }
869
870 pub fn kind(&self) -> &rustdoc_types::VariantKind {
871 &self.variant.kind
872 }
873
874 pub fn discriminant(&self) -> Option<&rustdoc_types::Discriminant> {
875 self.variant.discriminant.as_ref()
876 }
877}
878
879#[derive(Debug, Copy, Clone, PartialEq, Eq)]
880pub struct UnionItem<'a> {
881 krate: &'a Crate,
882 item: &'a rustdoc_types::Item,
883 union: &'a rustdoc_types::Union,
884}
885
886impl<'a> CrateItem<'a> for UnionItem<'a> {
887 type Inner = rustdoc_types::Union;
888 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
889 match inner {
890 rustdoc_types::ItemEnum::Union(union) => Some(union),
891 _ => None,
892 }
893 }
894 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, union: &'a Self::Inner) -> Self {
895 Self { krate, item, union }
896 }
897 fn item(&self) -> &'a rustdoc_types::Item {
898 self.item
899 }
900 fn inner(&self) -> &'a Self::Inner {
901 self.union
902 }
903 fn krate(&self) -> &'a Crate {
904 self.krate
905 }
906}
907
908impl HasName for UnionItem<'_> {
909 fn name(&self) -> &str {
910 self.item.name.as_ref().unwrap()
911 }
912}
913
914impl<'a> UnionItem<'a> {
915 pub fn name(&self) -> &str {
916 self.item.name.as_ref().unwrap()
917 }
918
919 pub fn field_ids(&self) -> impl Iterator<Item = &Id> {
920 self.union.fields.iter()
921 }
922
923 pub fn fields(&self) -> impl Iterator<Item = FieldItem<'_>> {
924 self.field_ids().map(|id| {
925 let item = &self.krate.index[id];
926 let rustdoc_types::ItemEnum::StructField(field) = &item.inner else {
927 panic!("expected struct field, got {:?}", item.inner);
928 };
929 FieldItem {
930 krate: self.krate,
931 item,
932 field,
933 }
934 })
935 }
936
937 pub fn impl_ids(&self) -> impl Iterator<Item = &Id> {
938 self.union.impls.iter()
939 }
940
941 pub fn impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
942 self.impl_ids().map(|id| {
943 let item = &self.krate.index[id];
944 let rustdoc_types::ItemEnum::Impl(imp) = &item.inner else {
945 panic!("expected impl, got {:?}", item.inner);
946 };
947 ImplItem {
948 krate: self.krate,
949 item,
950 impl_: imp,
951 }
952 })
953 }
954
955 pub fn trait_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
956 self.impls().filter(|imp| imp.trait_().is_some())
957 }
958
959 pub fn blanket_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
960 self.trait_impls()
961 .filter(|imp| imp.impl_.blanket_impl.is_some())
962 }
963
964 pub fn non_blanket_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
965 self.trait_impls()
966 .filter(|imp| imp.impl_.blanket_impl.is_none())
967 }
968
969 pub fn associated_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
971 self.impls().filter(|imp| imp.trait_().is_none())
972 }
973
974 pub fn generics(&self) -> &rustdoc_types::Generics {
975 &self.union.generics
976 }
977
978 pub fn has_stripped_fields(&self) -> bool {
979 self.union.has_stripped_fields
980 }
981}
982
983#[derive(Debug, Copy, Clone, PartialEq, Eq)]
984pub struct TypeAliasItem<'a> {
985 krate: &'a Crate,
986 item: &'a rustdoc_types::Item,
987 type_alias: &'a rustdoc_types::TypeAlias,
988}
989
990impl<'a> CrateItem<'a> for TypeAliasItem<'a> {
991 type Inner = rustdoc_types::TypeAlias;
992 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
993 match inner {
994 rustdoc_types::ItemEnum::TypeAlias(type_alias) => Some(type_alias),
995 _ => None,
996 }
997 }
998 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, type_alias: &'a Self::Inner) -> Self {
999 Self {
1000 krate,
1001 item,
1002 type_alias,
1003 }
1004 }
1005 fn item(&self) -> &'a rustdoc_types::Item {
1006 self.item
1007 }
1008 fn inner(&self) -> &'a Self::Inner {
1009 self.type_alias
1010 }
1011 fn krate(&self) -> &'a Crate {
1012 self.krate
1013 }
1014}
1015
1016impl HasName for TypeAliasItem<'_> {
1017 fn name(&self) -> &str {
1018 self.item.name.as_ref().unwrap()
1019 }
1020}
1021
1022impl<'a> TypeAliasItem<'a> {
1023 pub fn name(&self) -> &str {
1024 self.item.name.as_ref().unwrap()
1025 }
1026
1027 pub fn type_(&self) -> &Type {
1028 &self.type_alias.type_
1029 }
1030
1031 pub fn generics(&self) -> &rustdoc_types::Generics {
1032 &self.type_alias.generics
1033 }
1034}
1035
1036#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1037pub struct TraitAliasItem<'a> {
1038 krate: &'a Crate,
1039 item: &'a rustdoc_types::Item,
1040 trait_alias: &'a rustdoc_types::TraitAlias,
1041}
1042
1043impl<'a> CrateItem<'a> for TraitAliasItem<'a> {
1044 type Inner = rustdoc_types::TraitAlias;
1045 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
1046 match inner {
1047 rustdoc_types::ItemEnum::TraitAlias(trait_alias) => Some(trait_alias),
1048 _ => None,
1049 }
1050 }
1051 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, trait_alias: &'a Self::Inner) -> Self {
1052 Self {
1053 krate,
1054 item,
1055 trait_alias,
1056 }
1057 }
1058 fn item(&self) -> &'a rustdoc_types::Item {
1059 self.item
1060 }
1061 fn inner(&self) -> &'a Self::Inner {
1062 self.trait_alias
1063 }
1064 fn krate(&self) -> &'a Crate {
1065 self.krate
1066 }
1067}
1068
1069impl HasName for TraitAliasItem<'_> {
1070 fn name(&self) -> &str {
1071 self.item.name.as_ref().unwrap()
1072 }
1073}
1074
1075impl<'a> TraitAliasItem<'a> {
1076 pub fn name(&self) -> &str {
1077 self.item.name.as_ref().unwrap()
1078 }
1079
1080 pub fn generics(&self) -> &rustdoc_types::Generics {
1081 &self.trait_alias.generics
1082 }
1083
1084 pub fn params(&self) -> &[rustdoc_types::GenericBound] {
1085 &self.trait_alias.params
1086 }
1087}
1088
1089#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1090pub struct ImplItem<'a> {
1091 krate: &'a Crate,
1092 item: &'a rustdoc_types::Item,
1093 impl_: &'a rustdoc_types::Impl,
1094}
1095
1096impl<'a> CrateItem<'a> for ImplItem<'a> {
1097 type Inner = rustdoc_types::Impl;
1098 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
1099 match inner {
1100 rustdoc_types::ItemEnum::Impl(impl_) => Some(impl_),
1101 _ => None,
1102 }
1103 }
1104 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, impl_: &'a Self::Inner) -> Self {
1105 Self { krate, item, impl_ }
1106 }
1107 fn item(&self) -> &'a rustdoc_types::Item {
1108 self.item
1109 }
1110 fn inner(&self) -> &'a Self::Inner {
1111 self.impl_
1112 }
1113 fn krate(&self) -> &'a Crate {
1114 self.krate
1115 }
1116}
1117
1118impl<'a> ImplItem<'a> {
1119 pub fn id(&self) -> &Id {
1120 &self.item.id
1121 }
1122
1123 pub fn item_ids(&self) -> impl Iterator<Item = &Id> {
1124 self.impl_.items.iter()
1125 }
1126
1127 pub fn items(&self) -> impl Iterator<Item = &rustdoc_types::Item> {
1128 self.item_ids().map(|id| &self.krate.index[id])
1129 }
1130
1131 pub fn trait_(&self) -> Option<&rustdoc_types::Path> {
1132 self.impl_.trait_.as_ref()
1133 }
1134
1135 pub fn for_(&self) -> &rustdoc_types::Type {
1136 &self.impl_.for_
1137 }
1138
1139 pub fn is_unsafe(&self) -> bool {
1140 self.impl_.is_unsafe
1141 }
1142
1143 pub fn generics(&self) -> &rustdoc_types::Generics {
1144 &self.impl_.generics
1145 }
1146
1147 pub fn provided_trait_methods(&self) -> &[String] {
1148 &self.impl_.provided_trait_methods
1149 }
1150}
1151
1152impl_items!(ImplItem<'a>);
1153
1154#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1155pub struct MacroItem<'a> {
1156 krate: &'a Crate,
1157 item: &'a rustdoc_types::Item,
1158 macro_: &'a String,
1159}
1160
1161impl<'a> CrateItem<'a> for MacroItem<'a> {
1162 type Inner = String;
1163 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
1164 match inner {
1165 rustdoc_types::ItemEnum::Macro(macro_) => Some(macro_),
1166 _ => None,
1167 }
1168 }
1169 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, macro_: &'a Self::Inner) -> Self {
1170 Self {
1171 krate,
1172 item,
1173 macro_,
1174 }
1175 }
1176 fn item(&self) -> &'a rustdoc_types::Item {
1177 self.item
1178 }
1179 fn inner(&self) -> &'a Self::Inner {
1180 self.macro_
1181 }
1182 fn krate(&self) -> &'a Crate {
1183 self.krate
1184 }
1185}
1186
1187impl HasName for MacroItem<'_> {
1188 fn name(&self) -> &str {
1189 self.item.name.as_ref().unwrap()
1190 }
1191}
1192
1193impl<'a> MacroItem<'a> {
1194 pub fn name(&self) -> &str {
1195 self.item.name.as_ref().unwrap()
1196 }
1197
1198 pub fn macro_(&self) -> &str {
1199 self.macro_
1200 }
1201}
1202
1203pub struct UseItem<'a> {
1204 krate: &'a Crate,
1205 item: &'a rustdoc_types::Item,
1206 import: &'a rustdoc_types::Use,
1207}
1208
1209impl<'a> CrateItem<'a> for UseItem<'a> {
1210 type Inner = rustdoc_types::Use;
1211 fn downcast(inner: &rustdoc_types::ItemEnum) -> Option<&Self::Inner> {
1212 match inner {
1213 rustdoc_types::ItemEnum::Use(import) => Some(import),
1214 _ => None,
1215 }
1216 }
1217 fn new(krate: &'a Crate, item: &'a rustdoc_types::Item, import: &'a Self::Inner) -> Self {
1218 Self {
1219 krate,
1220 item,
1221 import,
1222 }
1223 }
1224 fn item(&self) -> &'a rustdoc_types::Item {
1225 self.item
1226 }
1227 fn inner(&self) -> &'a Self::Inner {
1228 self.import
1229 }
1230 fn krate(&self) -> &'a Crate {
1231 self.krate
1232 }
1233}
1234
1235impl UseItem<'_> {
1236 pub fn as_name(&self) -> &str {
1244 &self.import.name
1245 }
1246
1247 pub fn source(&self) -> &str {
1255 &self.import.source
1256 }
1257
1258 pub fn is_glob(&self) -> bool {
1259 self.import.is_glob
1260 }
1261}
1262
1263#[derive(Clone, PartialEq, Eq)]
1264pub struct Crate(rustdoc_types::Crate);
1265
1266impl std::fmt::Debug for Crate {
1267 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1268 f.debug_struct("Crate")
1269 .field("root", &self.root)
1270 .field("crate_version", &self.crate_version)
1271 .field("...", &"...")
1272 .finish()
1273 }
1274}
1275
1276impl Deref for Crate {
1277 type Target = rustdoc_types::Crate;
1278
1279 fn deref(&self) -> &Self::Target {
1280 &self.0
1281 }
1282}
1283
1284impl Crate {
1285 pub fn all_items(&self) -> impl Iterator<Item = &rustdoc_types::Item> {
1287 self.0.index.values()
1288 }
1289
1290 pub fn items(&self) -> impl Iterator<Item = &rustdoc_types::Item> {
1292 self.all_items().filter(|&item| item.crate_id == 0)
1293 }
1294
1295 pub fn krate(&self) -> &Crate {
1296 self
1297 }
1298
1299 pub fn item_summary(&self) -> impl Iterator<Item = &rustdoc_types::ItemSummary> {
1300 self.0.paths.values()
1301 }
1302
1303 pub fn downcast<'a, T: CrateItem<'a> + 'a>(
1305 &'a self,
1306 item: &'a rustdoc_types::Item,
1307 ) -> Option<T> {
1308 let inner = T::downcast(&item.inner)?;
1309 Some(T::new(self, item, inner))
1310 }
1311
1312 pub fn all_modules(&self) -> impl Iterator<Item = ModuleItem<'_>> {
1313 self.all_items()
1314 .filter_map(|item| self.krate().downcast::<ModuleItem>(item))
1315 }
1316
1317 pub fn modules(&self) -> impl Iterator<Item = ModuleItem<'_>> {
1319 self.all_modules().filter(|module| module.is_crate_item())
1320 }
1321
1322 pub fn sub_modules(&self) -> impl Iterator<Item = ModuleItem<'_>> {
1326 self.all_modules().filter(|module| {
1327 module
1328 .parent()
1329 .is_some_and(|parent| parent.id() == &self.root)
1330 })
1331 }
1332
1333 pub fn all_functions(&self) -> impl Iterator<Item = FunctionItem<'_>> {
1336 self.all_items()
1337 .filter_map(|item| self.krate().downcast::<FunctionItem>(item))
1338 }
1339
1340 pub fn functions(&self) -> impl Iterator<Item = FunctionItem<'_>> {
1343 self.all_functions().filter(|func| {
1344 func.is_root_item() && !func.is_method() && !func.is_associated() && func.func.has_body
1345 })
1346 }
1347
1348 pub fn all_constants(&self) -> impl Iterator<Item = ConstantItem<'_>> {
1350 self.all_items()
1351 .filter_map(|item| self.krate().downcast::<ConstantItem>(item))
1352 }
1353
1354 pub fn constants(&self) -> impl Iterator<Item = ConstantItem<'_>> {
1356 self.all_constants()
1357 .filter(|constant| constant.is_root_item())
1358 }
1359
1360 pub fn all_statics(&self) -> impl Iterator<Item = StaticItem<'_>> {
1362 self.all_items()
1363 .filter_map(|item| self.krate().downcast::<StaticItem>(item))
1364 }
1365
1366 pub fn statics(&self) -> impl Iterator<Item = StaticItem<'_>> {
1368 self.all_statics().filter(|static_| static_.is_root_item())
1369 }
1370
1371 pub fn all_structs(&self) -> impl Iterator<Item = StructItem<'_>> {
1373 self.all_items()
1374 .filter_map(|item| self.krate().downcast::<StructItem>(item))
1375 }
1376
1377 pub fn structs(&self) -> impl Iterator<Item = StructItem<'_>> {
1379 self.all_structs().filter(|struct_| struct_.is_root_item())
1380 }
1381
1382 pub fn all_traits(&self) -> impl Iterator<Item = TraitItem<'_>> {
1384 self.all_items()
1385 .filter_map(|item| self.krate().downcast::<TraitItem>(item))
1386 }
1387
1388 pub fn traits(&self) -> impl Iterator<Item = TraitItem<'_>> {
1390 self.all_traits().filter(|trait_| trait_.is_root_item())
1391 }
1392
1393 pub fn all_enums(&self) -> impl Iterator<Item = EnumItem<'_>> {
1395 self.all_items()
1396 .filter_map(|item| self.krate().downcast::<EnumItem>(item))
1397 }
1398
1399 pub fn enums(&self) -> impl Iterator<Item = EnumItem<'_>> {
1401 self.all_enums().filter(|enum_| enum_.is_root_item())
1402 }
1403
1404 pub fn all_type_aliases(&self) -> impl Iterator<Item = TypeAliasItem<'_>> {
1405 self.all_items()
1406 .filter_map(|item| self.krate().downcast::<TypeAliasItem>(item))
1407 }
1408
1409 pub fn type_aliases(&self) -> impl Iterator<Item = TypeAliasItem<'_>> {
1410 self.all_type_aliases()
1411 .filter(|type_alias| type_alias.is_root_item())
1412 }
1413
1414 pub fn all_trait_aliases(&self) -> impl Iterator<Item = TraitAliasItem<'_>> {
1415 self.all_items()
1416 .filter_map(|item| self.krate().downcast::<TraitAliasItem>(item))
1417 }
1418
1419 pub fn trait_aliases(&self) -> impl Iterator<Item = TraitAliasItem<'_>> {
1420 self.all_trait_aliases()
1421 .filter(|trait_alias| trait_alias.is_root_item())
1422 }
1423
1424 pub fn all_unions(&self) -> impl Iterator<Item = UnionItem<'_>> {
1425 self.all_items()
1426 .filter_map(|item| self.krate().downcast::<UnionItem>(item))
1427 }
1428
1429 pub fn unions(&self) -> impl Iterator<Item = UnionItem<'_>> {
1430 self.all_unions().filter(|union| union.is_root_item())
1431 }
1432
1433 pub fn all_impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
1435 self.all_items()
1436 .filter_map(|item| self.krate().downcast::<ImplItem>(item))
1437 }
1438
1439 pub fn impls(&self) -> impl Iterator<Item = ImplItem<'_>> {
1441 self.all_impls().filter(|imp| imp.is_root_item())
1442 }
1443
1444 pub fn all_macros(&self) -> impl Iterator<Item = MacroItem<'_>> {
1446 self.all_items()
1447 .filter_map(|item| self.krate().downcast::<MacroItem>(item))
1448 }
1449
1450 pub fn macros(&self) -> impl Iterator<Item = MacroItem<'_>> {
1452 self.all_macros().filter(|macro_| macro_.is_root_item())
1453 }
1454
1455 pub fn all_uses(&self) -> impl Iterator<Item = UseItem<'_>> {
1457 self.all_items()
1458 .filter_map(|item| self.krate().downcast::<UseItem>(item))
1459 }
1460
1461 pub fn uses(&self) -> impl Iterator<Item = UseItem<'_>> {
1463 self.all_uses().filter(|import| import.is_root_item())
1464 }
1465
1466 pub fn get_item(&self, name: &str) -> Option<&rustdoc_types::Item> {
1468 self.items()
1469 .find(|item| item.name.as_ref().is_some_and(|n| n == name))
1470 }
1471
1472 pub fn get_constant(&self, name: &str) -> Option<ConstantItem<'_>> {
1474 self.constants().find(|constant| constant.name() == name)
1475 }
1476
1477 pub fn get_function(&self, name: &str) -> Option<FunctionItem<'_>> {
1479 self.functions().find(|func| func.name() == name)
1480 }
1481
1482 pub fn get_struct(&self, name: &str) -> Option<StructItem<'_>> {
1484 self.structs().find(|struct_| struct_.name() == name)
1485 }
1486
1487 pub fn get_enum(&self, name: &str) -> Option<EnumItem<'_>> {
1489 self.enums().find(|enum_| enum_.name() == name)
1490 }
1491
1492 pub fn get_trait(&self, name: &str) -> Option<TraitItem<'_>> {
1494 self.traits().find(|trait_| trait_.name() == name)
1495 }
1496
1497 pub fn get_type_alias(&self, name: &str) -> Option<TypeAliasItem<'_>> {
1499 self.type_aliases()
1500 .find(|type_alias| type_alias.name() == name)
1501 }
1502
1503 pub fn get_trait_alias(&self, name: &str) -> Option<TraitAliasItem<'_>> {
1505 self.trait_aliases()
1506 .find(|trait_alias| trait_alias.name() == name)
1507 }
1508
1509 pub fn get_union(&self, name: &str) -> Option<UnionItem<'_>> {
1511 self.unions().find(|union| union.name() == name)
1512 }
1513
1514 pub fn get_module(&self, name: &str) -> Option<ModuleItem<'_>> {
1516 self.modules().find(|module| module.name() == name)
1517 }
1518}
1519
1520#[derive(Debug)]
1521pub enum BuildCrateError {
1522 RustdocJson(rustdoc_json::BuildError),
1523 Io(std::io::Error),
1524 Serde(serde_json::Error),
1525}
1526
1527impl std::fmt::Display for BuildCrateError {
1528 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1529 match self {
1530 BuildCrateError::RustdocJson(err) => err.fmt(f),
1531 BuildCrateError::Io(err) => err.fmt(f),
1532 BuildCrateError::Serde(err) => err.fmt(f),
1533 }
1534 }
1535}
1536
1537impl std::error::Error for BuildCrateError {}
1538
1539impl From<rustdoc_json::BuildError> for BuildCrateError {
1540 fn from(err: rustdoc_json::BuildError) -> Self {
1541 Self::RustdocJson(err)
1542 }
1543}
1544
1545impl From<std::io::Error> for BuildCrateError {
1546 fn from(err: std::io::Error) -> Self {
1547 Self::Io(err)
1548 }
1549}
1550
1551impl From<serde_json::Error> for BuildCrateError {
1552 fn from(err: serde_json::Error) -> Self {
1553 Self::Serde(err)
1554 }
1555}
1556
1557#[derive(Default)]
1558pub struct CrateBuilder {
1559 builder: rustdoc_json::Builder,
1560}
1561
1562impl CrateBuilder {
1563 pub fn new() -> Self {
1564 Self {
1565 builder: rustdoc_json::Builder::default(),
1566 }
1567 }
1568
1569 pub fn toolchain(mut self, toolchain: impl Into<String>) -> Self {
1570 self.builder = self.builder.toolchain(toolchain);
1571 self
1572 }
1573
1574 pub fn manifest_path(mut self, manifest_path: impl AsRef<Path>) -> Self {
1575 self.builder = self.builder.manifest_path(manifest_path);
1576 self
1577 }
1578
1579 pub fn all_features(mut self, all_features: bool) -> Self {
1580 self.builder = self.builder.all_features(all_features);
1581 self
1582 }
1583
1584 pub fn package(mut self, package: impl AsRef<str>) -> Self {
1585 self.builder = self.builder.package(package);
1586 self
1587 }
1588
1589 pub fn features(mut self, features: impl IntoIterator<Item = impl AsRef<str>>) -> Self {
1590 self.builder = self.builder.features(features);
1591 self
1592 }
1593
1594 pub fn no_default_features(mut self, no_default_features: bool) -> Self {
1595 self.builder = self.builder.no_default_features(no_default_features);
1596 self
1597 }
1598
1599 pub fn target(mut self, target: String) -> Self {
1600 self.builder = self.builder.target(target);
1601 self
1602 }
1603
1604 pub fn target_dir(mut self, target_dir: impl AsRef<Path>) -> Self {
1605 self.builder = self.builder.target_dir(target_dir);
1606 self
1607 }
1608
1609 pub fn document_private_items(mut self, document_private_items: bool) -> Self {
1610 self.builder = self.builder.document_private_items(document_private_items);
1611 self
1612 }
1613
1614 pub fn quiet(mut self, quiet: bool) -> Self {
1615 self.builder = self.builder.quiet(quiet);
1616 self
1617 }
1618
1619 pub fn silent(mut self, silent: bool) -> Self {
1620 self.builder = self.builder.silent(silent);
1621 self
1622 }
1623
1624 pub fn color(mut self, color: Color) -> Self {
1625 self.builder = self.builder.color(color);
1626 self
1627 }
1628
1629 pub fn color_always(mut self, color_always: bool) -> Self {
1630 if color_always {
1631 self.builder = self.builder.color(Color::Always);
1632 }
1633 self
1634 }
1635
1636 pub fn color_never(mut self, color_never: bool) -> Self {
1637 if color_never {
1638 self.builder = self.builder.color(Color::Never);
1639 }
1640 self
1641 }
1642
1643 pub fn cap_lints(mut self, cap_lints: Option<impl AsRef<str>>) -> Self {
1644 self.builder = self.builder.cap_lints(cap_lints);
1645 self
1646 }
1647
1648 pub fn build(self) -> Result<Crate, BuildCrateError> {
1649 let path = self.builder.build()?;
1650 let krate = serde_json::from_reader(std::fs::File::open(path)?).map(Crate)?;
1651 Ok(krate)
1652 }
1653
1654 pub fn build_with_captured_output(
1655 self,
1656 stdout: impl Write,
1657 stderr: impl Write,
1658 ) -> Result<Crate, BuildCrateError> {
1659 let path = self.builder.build_with_captured_output(stdout, stderr)?;
1660 let krate = serde_json::from_reader(std::fs::File::open(path)?).map(Crate)?;
1661 Ok(krate)
1662 }
1663}