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