1use std::fmt::{self, Display};
8
9use crate::def::DefKind;
10use crate::{Item, ItemKind, TraitItem, TraitItemKind, hir};
11
12#[derive(Copy, Clone, PartialEq, Debug)]
13pub enum GenericParamKind {
14 Type,
15 Lifetime,
16 Const,
17}
18
19#[derive(Copy, Clone, PartialEq, Debug)]
20pub enum MethodKind {
21 Trait { body: bool },
22 Inherent,
23}
24
25#[derive(Copy, Clone, PartialEq, Debug)]
26pub enum Target {
27 ExternCrate,
28 Use,
29 Static,
30 Const,
31 Fn,
32 Closure,
33 Mod,
34 ForeignMod,
35 GlobalAsm,
36 TyAlias,
37 Enum,
38 Variant,
39 Struct,
40 Field,
41 Union,
42 Trait,
43 TraitAlias,
44 Impl,
45 Expression,
46 Statement,
47 Arm,
48 AssocConst,
49 Method(MethodKind),
50 AssocTy,
51 ForeignFn,
52 ForeignStatic,
53 ForeignTy,
54 GenericParam(GenericParamKind),
55 MacroDef,
56 Param,
57 PatField,
58 ExprField,
59}
60
61impl Display for Target {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(f, "{}", Self::name(*self))
64 }
65}
66
67impl Target {
68 pub fn is_associated_item(self) -> bool {
69 match self {
70 Target::AssocConst | Target::AssocTy | Target::Method(_) => true,
71 Target::ExternCrate
72 | Target::Use
73 | Target::Static
74 | Target::Const
75 | Target::Fn
76 | Target::Closure
77 | Target::Mod
78 | Target::ForeignMod
79 | Target::GlobalAsm
80 | Target::TyAlias
81 | Target::Enum
82 | Target::Variant
83 | Target::Struct
84 | Target::Field
85 | Target::Union
86 | Target::Trait
87 | Target::TraitAlias
88 | Target::Impl
89 | Target::Expression
90 | Target::Statement
91 | Target::Arm
92 | Target::ForeignFn
93 | Target::ForeignStatic
94 | Target::ForeignTy
95 | Target::GenericParam(_)
96 | Target::MacroDef
97 | Target::Param
98 | Target::PatField
99 | Target::ExprField => false,
100 }
101 }
102
103 pub fn from_item(item: &Item<'_>) -> Target {
104 match item.kind {
105 ItemKind::ExternCrate(..) => Target::ExternCrate,
106 ItemKind::Use(..) => Target::Use,
107 ItemKind::Static { .. } => Target::Static,
108 ItemKind::Const(..) => Target::Const,
109 ItemKind::Fn { .. } => Target::Fn,
110 ItemKind::Macro(..) => Target::MacroDef,
111 ItemKind::Mod(..) => Target::Mod,
112 ItemKind::ForeignMod { .. } => Target::ForeignMod,
113 ItemKind::GlobalAsm(..) => Target::GlobalAsm,
114 ItemKind::TyAlias(..) => Target::TyAlias,
115 ItemKind::Enum(..) => Target::Enum,
116 ItemKind::Struct(..) => Target::Struct,
117 ItemKind::Union(..) => Target::Union,
118 ItemKind::Trait(..) => Target::Trait,
119 ItemKind::TraitAlias(..) => Target::TraitAlias,
120 ItemKind::Impl { .. } => Target::Impl,
121 }
122 }
123
124 pub fn from_def_kind(def_kind: DefKind) -> Target {
126 match def_kind {
127 DefKind::ExternCrate => Target::ExternCrate,
128 DefKind::Use => Target::Use,
129 DefKind::Static { .. } => Target::Static,
130 DefKind::Const => Target::Const,
131 DefKind::Fn => Target::Fn,
132 DefKind::Macro(..) => Target::MacroDef,
133 DefKind::Mod => Target::Mod,
134 DefKind::ForeignMod => Target::ForeignMod,
135 DefKind::GlobalAsm => Target::GlobalAsm,
136 DefKind::TyAlias => Target::TyAlias,
137 DefKind::Enum => Target::Enum,
138 DefKind::Struct => Target::Struct,
139 DefKind::Union => Target::Union,
140 DefKind::Trait => Target::Trait,
141 DefKind::TraitAlias => Target::TraitAlias,
142 DefKind::Impl { .. } => Target::Impl,
143 _ => panic!("impossible case reached"),
144 }
145 }
146
147 pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
148 match trait_item.kind {
149 TraitItemKind::Const(..) => Target::AssocConst,
150 TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => {
151 Target::Method(MethodKind::Trait { body: false })
152 }
153 TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => {
154 Target::Method(MethodKind::Trait { body: true })
155 }
156 TraitItemKind::Type(..) => Target::AssocTy,
157 }
158 }
159
160 pub fn from_foreign_item(foreign_item: &hir::ForeignItem<'_>) -> Target {
161 match foreign_item.kind {
162 hir::ForeignItemKind::Fn(..) => Target::ForeignFn,
163 hir::ForeignItemKind::Static(..) => Target::ForeignStatic,
164 hir::ForeignItemKind::Type => Target::ForeignTy,
165 }
166 }
167
168 pub fn from_generic_param(generic_param: &hir::GenericParam<'_>) -> Target {
169 match generic_param.kind {
170 hir::GenericParamKind::Type { .. } => Target::GenericParam(GenericParamKind::Type),
171 hir::GenericParamKind::Lifetime { .. } => {
172 Target::GenericParam(GenericParamKind::Lifetime)
173 }
174 hir::GenericParamKind::Const { .. } => Target::GenericParam(GenericParamKind::Const),
175 }
176 }
177
178 pub fn name(self) -> &'static str {
179 match self {
180 Target::ExternCrate => "extern crate",
181 Target::Use => "use",
182 Target::Static => "static item",
183 Target::Const => "constant item",
184 Target::Fn => "function",
185 Target::Closure => "closure",
186 Target::Mod => "module",
187 Target::ForeignMod => "foreign module",
188 Target::GlobalAsm => "global asm",
189 Target::TyAlias => "type alias",
190 Target::Enum => "enum",
191 Target::Variant => "enum variant",
192 Target::Struct => "struct",
193 Target::Field => "struct field",
194 Target::Union => "union",
195 Target::Trait => "trait",
196 Target::TraitAlias => "trait alias",
197 Target::Impl => "implementation block",
198 Target::Expression => "expression",
199 Target::Statement => "statement",
200 Target::Arm => "match arm",
201 Target::AssocConst => "associated const",
202 Target::Method(kind) => match kind {
203 MethodKind::Inherent => "inherent method",
204 MethodKind::Trait { body: false } => "required trait method",
205 MethodKind::Trait { body: true } => "provided trait method",
206 },
207 Target::AssocTy => "associated type",
208 Target::ForeignFn => "foreign function",
209 Target::ForeignStatic => "foreign static item",
210 Target::ForeignTy => "foreign type",
211 Target::GenericParam(kind) => match kind {
212 GenericParamKind::Type => "type parameter",
213 GenericParamKind::Lifetime => "lifetime parameter",
214 GenericParamKind::Const => "const parameter",
215 },
216 Target::MacroDef => "macro def",
217 Target::Param => "function param",
218 Target::PatField => "pattern field",
219 Target::ExprField => "struct field",
220 }
221 }
222}