1#[macro_use]
5mod err;
6mod ast;
7mod ctxt;
8mod expand;
9
10use syn::{parse_macro_input, DeriveInput};
14use thiserror::Error;
15
16use crate::ast::symbol;
20use crate::ctxt::Ctxt;
21
22const CRATE_NAME: &str = "tinyklv";
26const DERIVE_NAME: &str = "Klv";
27const ATTR_NAME: &str = "klv";
28
29#[proc_macro_derive(Klv, attributes(klv))]
30pub fn klv_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
32 let input = parse_macro_input!(input as DeriveInput);
33 expand::derive(&input)
34 .unwrap_or_else(syn::Error::into_compile_error)
35 .into()
36}
37
38#[derive(Debug, Error)]
39enum Error {
41 #[error("\
45 {c} does not support #[derive({d})] for {0}s.",
46 c = CRATE_NAME,
47 d = DERIVE_NAME,
48 )]
49 UnsupportedContainer(String),
50
51 #[error("\
52 {c} does not support #[derive({d})] for structs with unnamed fields (tuple-structs).",
53 c = CRATE_NAME,
54 d = DERIVE_NAME,
55 )]
56 UnsupportedUnnamedStructs,
57
58 #[error("\
59 {c} does not support #[derive({d})] for unit-structs.",
60 c = CRATE_NAME,
61 d = DERIVE_NAME,
62 )]
63 UnsupportedUnitStructs,
64
65 #[error("\
69 Unknown attribute: `{0}`.
70Expected {s}.",
71 s = symbol::CONT_SYMBOLS,
72 )]
73 UnknownContainerAttribute(String),
74
75 #[error("\
76 Unknown list attribute: `{0}(..)`.
77Options include {s}.",
78 s = symbol::CONT_LIST_SYMBOLS,
79 )]
80 UnknownContainerListAttribute(String),
81
82 #[error("\
83 Unknown name-value attribute: `{0} = <value>`.
84Options include {s}.",
85 s = symbol::CONT_NV_SYMBOLS,
86 )]
87 UnknownContainerNameValueAttribute(String),
88
89 #[error("\
90 Expected `{0}` to be a list attribute: `#[{k}({0}(..),)]`.",
91 k = symbol::KLV_ATTR,
92 )]
93 ExpectedAsList(String),
94
95 #[error("\
96 Expected `{0}` to be a name-value attribute: `#[{k}({0} = <..>,)]`.",
97 k = symbol::KLV_ATTR,
98 )]
99 ExpectedAsNameValue(String),
100
101 #[error("\
102 Expected `{0}` to be a path attribute: `#[{k}({0},)]`.",
103 k = symbol::KLV_ATTR,
104 )]
105 ExpectedAsPath(String),
106
107 #[error("\
111 Duplicate `{s}` attribute. Only one stream-type per struct is supported.",
112 s = symbol::STREAM,
113 )]
114 DuplicateStream,
115
116 #[error("\
120 Duplicate `{s}` attribute. Currently, only one sentinel is supported per struct.",
121 s = symbol::SENTINEL,
122 )]
123 DuplicateSentinel,
124
125 #[error("\
129 Missing required `{s}` field to describe how to encode/decode key values.",
130 s = symbol::KEY,
131 )]
132 MissingKey,
133
134 #[error("\
135 Missing required `{s}` field to describe how to encode/decode length values.",
136 s = symbol::LENGTH,
137 )]
138 MissingLength,
139
140 #[error("\
141 Duplicate `{s}` attribute. Only one method of encoding and decoding keys is allowed.",
142 s = symbol::KEY,
143 )]
144 DuplicateKey,
145
146 #[error("\
147 Duplicate `{s}` attribute. Only one method of encoding and decoding lengths is allowed.",
148 s = symbol::LENGTH,
149 )]
150 DuplicateLength,
151
152 #[error("\
153 Unknown field `{0}` in {k}/{l}.
154Expected `{e} = <..>` or `{d} = <..>`.",
155 k = symbol::KEY,
156 l = symbol::LENGTH,
157 e = symbol::ENCODER,
158 d = symbol::DECODER,
159 )]
160 UnknownKeyLenField(String),
161
162 #[error("\
163 Duplicate `{e}` field. Only one method of encoding {k}/{l} is allowed.",
164 e = symbol::ENCODER,
165 k = symbol::KEY,
166 l = symbol::LENGTH,
167 )]
168 DuplicateEncoderInKeyLen,
169
170 #[error("\
171 Duplicate `{d}` field. Only one method of decoding {k}/{l} is allowed.",
172 d = symbol::DECODER,
173 k = symbol::KEY,
174 l = symbol::LENGTH,
175 )]
176 DuplicateDecoderInKeyLen,
177
178 #[error("\
179 Missing required `{e}` field for `{0}`.
180If no encoding is required, use `#[{a}({aue})]`.",
181 e = symbol::ENCODER,
182 a = symbol::KLV_ATTR,
183 aue = symbol::ALLOW_UNIMPLEMENTED_ENCODE,
184 )]
185 MissingEncInKeyLen(String),
186
187 #[error("\
188 Missing required `{d}` field for `{0}`.
189If no decoding is required, use `#[{a}({aud})]`.",
190 d = symbol::DECODER,
191 a = symbol::KLV_ATTR,
192 aud = symbol::ALLOW_UNIMPLEMENTED_DECODE,
193 )]
194 MissingDecInKeyLen(String),
195
196 #[error("\
200 Unknown default field: `{0}`.
201Expected {s}.",
202 s = symbol::CONT_DEFAULT_LIST_SYMBOLS,
203 )]
204 UnknownDefaultField(String),
205
206 #[error("\
207 Missing required `{s}` field for `{d}`.",
208 s = symbol::TYPE,
209 d = symbol::DEFAULT,
210 )]
211 MissingTypeInDefault,
212
213 #[error("\
214 Both `{e}` and `{d}` fields are missing: at least one is required.",
215 e = symbol::ENCODER,
216 d = symbol::DECODER,
217 )]
218 MissingEncDecInDefault,
219
220 #[error("\
221 Duplicate `{s}` field.
222To add multiple default encoder/decoders for types, add another `{d}` attribute.",
223 s = symbol::TYPE,
224 d = symbol::DEFAULT,
225 )]
226 DuplicateTypeInDefault,
227
228 #[error("\
229 Duplicate `{s}` field. Only one default encoder is allowed for {0} type.
230To add ways to encode said type, they must be done on a field-by-field basis and not using the `{d}` attribute.",
231 s = symbol::ENCODER,
232 d = symbol::DEFAULT,
233 )]
234 DuplicateEncoderInDefault(String),
235
236 #[error("\
237 Duplicate `{s}` field. Only one default decoder is allowed for {0} type.
238To add ways to decode said type, they must be done on a field-by-field basis and not using the `{d}` attribute.",
239 s = symbol::DECODER,
240 d = symbol::DEFAULT,
241 )]
242 DuplicateDecoderInDefault(String),
243
244 #[error("\
245 Duplicate `{s}` field. Only required once, defaults to `false`.",
246 s = symbol::VARIABLE_LENGTH,
247 )]
248 DuplicateVariableLengthInDefault,
249
250 #[error("\
251 Duplicate '{1}' found for `{d}({t} = {0})`. Only one default {1} is allowed per type.",
252 d = symbol::DEFAULT,
253 t = symbol::TYPE,
254 )]
255 DuplicateDefault(String, String),
256
257 #[error("\
261 Malformed `{s}` field. Expecting list: `{s}(..)`
262Options include {fs}.",
263 s = symbol::KLV_ATTR,
264 fs = symbol::FIELD_SYMBOLS,
265 )]
266 MalformedField,
267
268 #[error("\
269 Unknown field: `{0}`.
270Expected {s}.",
271 s = symbol::FIELD_SYMBOLS
272 )]
273 UnknownFieldField(String),
274
275 #[error("\
276 Duplicate `{s}` field.
277Currently only one key per field is supported.",
278 s = symbol::KEY,
279 )]
280 DuplicateKeyInField,
281
282 #[error("\
283 Duplicate `{s}` field.",
284 s = symbol::ENCODER,
285 )]
286 DuplicateEncoderInField,
287
288 #[error("\
289 Duplicate `{s}` field.",
290 s = symbol::DECODER,
291 )]
292 DuplicateDecoderInField,
293
294 #[error("\
295 Duplicate `{s}` field. Only required once, will default to `false`.",
296 s = symbol::VARIABLE_LENGTH,
297 )]
298 DuplicateVariableLengthInField,
299
300 #[error("\
301 Duplicate `{s}` field.",
302 s = symbol::LATEBIND,
303 )]
304 DuplicateLatebindInField,
305
306 #[error("\
307 Duplicate `{s}` field.",
308 s = symbol::DEFAULT_VALUE,
309 )]
310 DuplicateDefaultInField,
311
312 #[error("\
313 Missing required `{s}` field.",
314 s = symbol::KEY,
315 )]
316 MissingKeyInField,
317
318 #[error("\
319No encoder is found for field `{0}: {1}`.
320
321If encoding is not required, use `#[{k}({aue})]` on the struct.
322
323Otherwise, you can:
324 a. add a default encoder for all `{1}` types using `#[{k}({df}({t} = {1}, {e} = <..>)))]` on the struct
325 b. add an encoder to `{0}` using `#[{k}({e} = <..>)]`
326 c. set `#[{k}({fi})]` on the struct to fall back to try and use `tinyklv::EncodeValue` trait implementation",
327 k = symbol::KLV_ATTR,
328 df = symbol::DEFAULT,
329 t = symbol::TYPE,
330 e = symbol::ENCODER,
331 aue = symbol::ALLOW_UNIMPLEMENTED_ENCODE,
332 fi = symbol::TRAIT_FALLBACK,
333 )]
334 UnimplementedEncode(String, String),
335
336 #[error("\
337No decoder is found for field `{0}: {1}`.
338
339If decoding is not required, use `#[{k}({aud})]` on the struct.
340
341Otherwise, you can:
342 a. add a default decoder for all `{1}` types using `#[{k}({df}({t} = {1}, {d} = <..>)))]` on the struct
343 b. add a decoder to `{0}` using `#[{k}({d} = <..>)]`
344 c. set `#[{k}({fi})]` on the struct to fall back to try and use `tinyklv::DecodeValue` trait implementation",
345 k = symbol::KLV_ATTR,
346 df = symbol::DEFAULT,
347 t = symbol::TYPE,
348 d = symbol::DECODER,
349 aud = symbol::ALLOW_UNIMPLEMENTED_DECODE,
350 fi = symbol::TRAIT_FALLBACK,
351 )]
352 UnimplementedDecode(String, String),
353
354 #[error("\
355Field `{0}: {1}` has `{v} = true` but no `{d} = ..` was set.
356The trait fallback (`<{1} as ::tinyklv::DecodeValue<..>>::decode_value`) has no length argument - \
357supply an explicit `{d}` or remove `{v}`.",
358 v = symbol::VARIABLE_LENGTH,
359 d = symbol::DECODER,
360 )]
361 VarlenFallbackRequiresExplicitDec(String, String),
362}
363impl Error {
365 fn as_str(&self) -> std::borrow::Cow<'_, str> {
366 std::borrow::Cow::Owned(self.to_string())
367 }
368}