1#![allow(deprecated)] use std::convert::Infallible;
19use std::fmt::{self, Display, Formatter};
20
21use proc_macro2::Span;
22
23#[derive(Clone, Debug)]
25pub enum Error {
26 Parse(syn::Error),
28
29 NamesDontMatch(String, String),
31
32 MultipleSingularValues(String),
35
36 MultipleLiteralValues(String),
40
41 UnsupportedLiteral(String),
43
44 SingularAttrRequired(String),
46
47 ParametrizedAttrRequired(String),
49
50 AttributeUnknownArgument {
52 attr: String,
54 arg: String,
56 },
57
58 ArgTypeProhibited {
60 attr: String,
62 arg: String,
64 },
65
66 ArgNumberExceedsMax {
68 attr: String,
70 type_name: String,
72 no: usize,
74 max_no: u8,
76 },
77
78 ArgMustNotHaveValue {
80 attr: String,
82 arg: String,
84 },
85
86 ArgRequired {
88 attr: String,
90 arg: String,
92 },
93
94 ArgNameMustBeIdent,
97
98 ArgNameMustBeUnique {
101 attr: String,
103 arg: String,
105 },
106
107 ArgValueRequired {
110 attr: String,
112 arg: String,
114 },
115
116 ArgValueTypeMismatch {
118 attr: String,
120 arg: String,
122 },
123
124 ArgValueMustBeLiteral,
127
128 ArgValueMustBeType,
131
132 ArgValueMustBeExpr,
135
136 ParametrizedAttrHasNoValue(String),
139
140 #[deprecated(
143 since = "1.1.0",
144 note = "This error variant is not used anymore after the introduction of custom attribute \
145 parser"
146 )]
147 NestedListsNotSupported(String),
148}
149
150impl From<Infallible> for Error {
151 fn from(_: Infallible) -> Self { unreachable!() }
152}
153
154impl From<syn::Error> for Error {
155 fn from(err: syn::Error) -> Self { Error::Parse(err) }
156}
157
158impl From<Error> for syn::Error {
159 fn from(err: Error) -> Self { syn::Error::new(Span::call_site(), err.to_string()) }
160}
161
162impl Display for Error {
163 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
164 match self {
165 Error::Parse(err) => write!(f, "attribute parse error: {}", err),
166 Error::NamesDontMatch(name1, name2) => {
167 write!(f, "Names of two merged attributes (`{}` and `{}`) must match", name1, name2)
168 }
169 Error::MultipleSingularValues(name) => {
170 write!(f, "Multiple values assigned to `{}` attribute", name)
171 }
172 Error::MultipleLiteralValues(name) => {
173 write!(f, "Multiple literal values provided for `{}` attribute", name)
174 }
175 Error::SingularAttrRequired(name) => write!(
176 f,
177 "Attribute `{}` must be in a singular form (`#[attr]` or `#[attr = ...]`)",
178 name
179 ),
180 Error::ParametrizedAttrRequired(name) => {
181 write!(f, "Attribute `{}` must be in a parametrized form (`#[attr(...)]`)", name)
182 }
183 Error::ArgMustNotHaveValue { attr, arg } => write!(
184 f,
185 "Argument {arg} in `{attr}` attribute must not have a value",
186 attr = attr,
187 arg = arg
188 ),
189 Error::ArgTypeProhibited {
190 attr,
191 arg: type_name,
192 } => write!(f, "Attribute `{}` prohibits arguments of type `{}`", attr, type_name),
193 Error::ArgRequired { attr, arg } => write!(
194 f,
195 "Attribute `{}` requires argument `{}` to be explicitly specified",
196 attr, arg,
197 ),
198 Error::ArgNameMustBeUnique { attr, arg } => write!(
199 f,
200 "Argument names must be unique, while attribute `{}` contains multiple arguments \
201 with name`{}`",
202 attr, arg,
203 ),
204 Error::ArgNameMustBeIdent => {
205 write!(f, "Attribute arguments must be identifiers, not paths",)
206 }
207 Error::ArgValueRequired { attr, arg } => {
208 write!(f, "Attribute `{}` requires value for argument `{}`", attr, arg)
209 }
210 Error::ArgValueMustBeLiteral => {
211 f.write_str("Attribute argument value must be a literal (string, int etc)")
212 }
213 Error::ArgValueMustBeType => {
214 f.write_str("Attribute value for must be a valid type name")
215 }
216 Error::ArgValueMustBeExpr => {
217 f.write_str("Attribute value for must be a valid expression")
218 }
219 Error::ParametrizedAttrHasNoValue(name) => {
220 write!(f, "Attribute `{name}` must be in a `#[{name} = ...]` form", name = name)
221 }
222 Error::NestedListsNotSupported(name) => write!(
223 f,
224 "Attribute `{name}` must be in `{name} = ...` form and a nested list",
225 name = name,
226 ),
227 Error::UnsupportedLiteral(attr) => write!(
228 f,
229 "Attribute `{}` has an unsupported type of literal as one of its arguments",
230 attr
231 ),
232 Error::AttributeUnknownArgument { attr, arg } => {
233 write!(f, "Attribute `{}` has an unknown argument `{}`", attr, arg)
234 }
235 Error::ArgNumberExceedsMax {
236 attr,
237 type_name,
238 no,
239 max_no,
240 } => write!(
241 f,
242 "Attribute `{}` has excessive number of arguments of type `{}` ({} while only {} \
243 are allowed)",
244 attr, type_name, no, max_no
245 ),
246 Error::ArgValueTypeMismatch { attr, arg } => {
247 write!(f, "Type mismatch in attribute `{}` argument `{}`", attr, arg)
248 }
249 }
250 }
251}
252
253impl std::error::Error for Error {
254 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
255 match self {
256 Error::Parse(err) => Some(err),
257 Error::NamesDontMatch(_, _) |
258 Error::MultipleSingularValues(_) |
259 Error::MultipleLiteralValues(_) |
260 Error::SingularAttrRequired(_) |
261 Error::ArgMustNotHaveValue { .. } |
262 Error::ArgTypeProhibited { .. } |
263 Error::ArgRequired { .. } |
264 Error::ParametrizedAttrRequired(_) |
265 Error::ArgNameMustBeIdent |
266 Error::ArgNameMustBeUnique { .. } |
267 Error::ArgValueRequired { .. } |
268 Error::ArgValueMustBeLiteral |
269 Error::ArgValueMustBeType |
270 Error::ArgValueMustBeExpr |
271 Error::ParametrizedAttrHasNoValue(_) |
272 Error::UnsupportedLiteral(_) |
273 Error::AttributeUnknownArgument { .. } |
274 Error::ArgNumberExceedsMax { .. } |
275 Error::ArgValueTypeMismatch { .. } => None,
276 Error::NestedListsNotSupported(_) => None,
277 }
278 }
279}