1use std::fmt;
4
5use rustc_hir::def::{CtorOf, DefKind, MacroKinds};
6use rustc_span::hygiene::MacroKind;
7use serde::{Serialize, Serializer};
8
9use crate::clean;
10
11#[derive(Copy, PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
30#[repr(u8)]
31pub(crate) enum ItemType {
32 Keyword = 0,
33 Primitive = 1,
34 Module = 2,
35 ExternCrate = 3,
36 Import = 4,
37 Struct = 5,
38 Enum = 6,
39 Function = 7,
40 TypeAlias = 8,
41 Static = 9,
42 Trait = 10,
43 Impl = 11,
44 TyMethod = 12,
45 Method = 13,
46 StructField = 14,
47 Variant = 15,
48 Macro = 16,
49 AssocType = 17,
50 Constant = 18,
51 AssocConst = 19,
52 Union = 20,
53 ForeignType = 21,
54 ProcAttribute = 23,
56 ProcDerive = 24,
57 TraitAlias = 25,
58 }
61
62impl Serialize for ItemType {
63 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64 where
65 S: Serializer,
66 {
67 (*self as u8).serialize(serializer)
68 }
69}
70
71impl<'a> From<&'a clean::Item> for ItemType {
72 fn from(item: &'a clean::Item) -> ItemType {
73 let kind = match &item.kind {
74 clean::StrippedItem(box item) => item,
75 kind => kind,
76 };
77
78 match kind {
79 clean::ModuleItem(..) => ItemType::Module,
80 clean::ExternCrateItem { .. } => ItemType::ExternCrate,
81 clean::ImportItem(..) => ItemType::Import,
82 clean::StructItem(..) => ItemType::Struct,
83 clean::UnionItem(..) => ItemType::Union,
84 clean::EnumItem(..) => ItemType::Enum,
85 clean::FunctionItem(..) => ItemType::Function,
86 clean::TypeAliasItem(..) => ItemType::TypeAlias,
87 clean::StaticItem(..) => ItemType::Static,
88 clean::ConstantItem(..) => ItemType::Constant,
89 clean::TraitItem(..) => ItemType::Trait,
90 clean::ImplItem(..) => ItemType::Impl,
91 clean::RequiredMethodItem(..) => ItemType::TyMethod,
92 clean::MethodItem(..) => ItemType::Method,
93 clean::StructFieldItem(..) => ItemType::StructField,
94 clean::VariantItem(..) => ItemType::Variant,
95 clean::ForeignFunctionItem(..) => ItemType::Function, clean::ForeignStaticItem(..) => ItemType::Static, clean::MacroItem(..) => ItemType::Macro,
98 clean::PrimitiveItem(..) => ItemType::Primitive,
99 clean::RequiredAssocConstItem(..)
100 | clean::ProvidedAssocConstItem(..)
101 | clean::ImplAssocConstItem(..) => ItemType::AssocConst,
102 clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => ItemType::AssocType,
103 clean::ForeignTypeItem => ItemType::ForeignType,
104 clean::KeywordItem => ItemType::Keyword,
105 clean::TraitAliasItem(..) => ItemType::TraitAlias,
106 clean::ProcMacroItem(mac) => match mac.kind {
107 MacroKind::Bang => ItemType::Macro,
108 MacroKind::Attr => ItemType::ProcAttribute,
109 MacroKind::Derive => ItemType::ProcDerive,
110 },
111 clean::StrippedItem(..) => unreachable!(),
112 }
113 }
114}
115
116impl From<DefKind> for ItemType {
117 fn from(other: DefKind) -> Self {
118 Self::from_def_kind(other, None)
119 }
120}
121
122impl ItemType {
123 pub(crate) fn from_def_kind(kind: DefKind, parent_kind: Option<DefKind>) -> Self {
126 match kind {
127 DefKind::Enum => Self::Enum,
128 DefKind::Fn => Self::Function,
129 DefKind::Mod => Self::Module,
130 DefKind::Const => Self::Constant,
131 DefKind::Static { .. } => Self::Static,
132 DefKind::Struct => Self::Struct,
133 DefKind::Union => Self::Union,
134 DefKind::Trait => Self::Trait,
135 DefKind::TyAlias => Self::TypeAlias,
136 DefKind::TraitAlias => Self::TraitAlias,
137 DefKind::Macro(MacroKinds::BANG) => ItemType::Macro,
138 DefKind::Macro(MacroKinds::ATTR) => ItemType::ProcAttribute,
139 DefKind::Macro(MacroKinds::DERIVE) => ItemType::ProcDerive,
140 DefKind::Macro(_) => todo!("Handle macros with multiple kinds"),
141 DefKind::ForeignTy => Self::ForeignType,
142 DefKind::Variant => Self::Variant,
143 DefKind::Field => Self::StructField,
144 DefKind::AssocTy => Self::AssocType,
145 DefKind::AssocFn if let Some(DefKind::Trait) = parent_kind => Self::TyMethod,
146 DefKind::AssocFn => Self::Method,
147 DefKind::Ctor(CtorOf::Struct, _) => Self::Struct,
148 DefKind::Ctor(CtorOf::Variant, _) => Self::Variant,
149 DefKind::AssocConst => Self::AssocConst,
150 DefKind::TyParam
151 | DefKind::ConstParam
152 | DefKind::ExternCrate
153 | DefKind::Use
154 | DefKind::ForeignMod
155 | DefKind::AnonConst
156 | DefKind::InlineConst
157 | DefKind::OpaqueTy
158 | DefKind::LifetimeParam
159 | DefKind::GlobalAsm
160 | DefKind::Impl { .. }
161 | DefKind::Closure
162 | DefKind::SyntheticCoroutineBody => Self::ForeignType,
163 }
164 }
165
166 pub(crate) fn as_str(&self) -> &'static str {
167 match self {
168 ItemType::Module => "mod",
169 ItemType::ExternCrate => "externcrate",
170 ItemType::Import => "import",
171 ItemType::Struct => "struct",
172 ItemType::Union => "union",
173 ItemType::Enum => "enum",
174 ItemType::Function => "fn",
175 ItemType::TypeAlias => "type",
176 ItemType::Static => "static",
177 ItemType::Trait => "trait",
178 ItemType::Impl => "impl",
179 ItemType::TyMethod => "tymethod",
180 ItemType::Method => "method",
181 ItemType::StructField => "structfield",
182 ItemType::Variant => "variant",
183 ItemType::Macro => "macro",
184 ItemType::Primitive => "primitive",
185 ItemType::AssocType => "associatedtype",
186 ItemType::Constant => "constant",
187 ItemType::AssocConst => "associatedconstant",
188 ItemType::ForeignType => "foreigntype",
189 ItemType::Keyword => "keyword",
190 ItemType::ProcAttribute => "attr",
191 ItemType::ProcDerive => "derive",
192 ItemType::TraitAlias => "traitalias",
193 }
194 }
195 pub(crate) fn is_method(&self) -> bool {
196 matches!(self, ItemType::Method | ItemType::TyMethod)
197 }
198 pub(crate) fn is_adt(&self) -> bool {
199 matches!(self, ItemType::Struct | ItemType::Union | ItemType::Enum)
200 }
201}
202
203impl fmt::Display for ItemType {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 f.write_str(self.as_str())
206 }
207}