Skip to content

Commit 0cc1629

Browse files
Upgrade to syn 2.0 and synstructure 0.13
Close #6
1 parent 5d84e47 commit 0cc1629

File tree

2 files changed

+240
-111
lines changed

2 files changed

+240
-111
lines changed

derive/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ proc-macro = true
1515
[dependencies]
1616
proc-macro2 = "1"
1717
quote = "1"
18-
syn = "1"
19-
synstructure = "0.12"
18+
syn = "2"
19+
synstructure = "0.13"

derive/src/lib.rs

Lines changed: 238 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ use decodable::DeriveDecodableStruct;
1212
mod encodable;
1313
use encodable::DeriveEncodableStruct;
1414

15-
1615
use proc_macro2::TokenStream;
17-
use syn::{
18-
Attribute, Field, Ident, Lit, Meta, MetaList, MetaNameValue, NestedMeta,
19-
};
16+
use syn::{Attribute, Field, Ident, LitStr, Token};
2017
use synstructure::{decl_derive, Structure};
2118

2219
decl_derive!(
@@ -126,7 +123,7 @@ struct FieldAttrs {
126123
pub tag: Tag,
127124

128125
/// Whether the `#[tlv(slice)]` attribute was set
129-
pub slice: bool
126+
pub slice: bool,
130127
}
131128

132129
impl FieldAttrs {
@@ -150,116 +147,248 @@ fn extract_attrs_optional_tag(name: &Ident, attrs: &[Attribute]) -> (Option<Tag>
150147
let mut slice = false;
151148

152149
for attr in attrs {
153-
if !attr.path.is_ident("tlv") {
150+
if !attr.path().is_ident("tlv") {
154151
continue;
155152
}
156153

157-
match attr.parse_meta().expect("error parsing `tlv` attribute") {
158-
Meta::List(MetaList { nested, .. }) if !nested.is_empty() => {
159-
for entry in nested {
160-
match entry {
161-
NestedMeta::Meta(Meta::Path(path)) => {
162-
if path.is_ident("slice") {
163-
slice = true;
164-
} else if path.is_ident("universal") {
165-
tag = {
166-
let mut tag = if let Tag::Ber(tag) = tag {
167-
tag
168-
} else { Default::default() };
169-
tag.class = Class::Universal;
170-
tag.into()
171-
};
172-
} else if path.is_ident("application") {
173-
tag = {
174-
let mut tag = if let Tag::Ber(tag) = tag {
175-
tag
176-
} else { Default::default() };
177-
tag.class = Class::Application;
178-
tag.into()
179-
};
180-
} else if path.is_ident("context") {
181-
tag = {
182-
let mut tag = if let Tag::Ber(tag) = tag {
183-
tag
184-
} else { Default::default() };
185-
tag.class = Class::Context;
186-
tag.into()
187-
};
188-
} else if path.is_ident("private") {
189-
tag = {
190-
let mut tag = if let Tag::Ber(tag) = tag {
191-
tag
192-
} else { Default::default() };
193-
tag.class = Class::Private;
194-
tag.into()
195-
};
196-
} else if path.is_ident("constructed") {
197-
tag = {
198-
let mut tag = if let Tag::Ber(tag) = tag {
199-
tag
200-
} else { Default::default() };
201-
tag.constructed = true;
202-
tag.into()
203-
};
204-
} else if path.is_ident("primitive") {
205-
tag = {
206-
let mut tag = if let Tag::Ber(tag) = tag {
207-
tag
208-
} else { Default::default() };
209-
tag.constructed = false;
210-
tag.into()
211-
};
212-
} else {
213-
panic!("unknown `tlv` attribute for field `{}`: {:?}", name, path);
214-
}
215-
}
216-
NestedMeta::Meta(Meta::NameValue(MetaNameValue {
217-
path,
218-
lit: Lit::Str(lit_str),
219-
..
220-
})) => {
221-
// Parse the `type = "..."` attribute
222-
if path.is_ident("number") {
223-
tag = {
224-
let possibly_with_prefix = lit_str.value();
225-
let without_prefix = possibly_with_prefix.trim_start_matches("0x");
226-
let tag_number = u16::from_str_radix(without_prefix, 16).expect("tag values must be between one and 254");
227-
let mut tag = if let Tag::Ber(tag) = tag {
228-
tag
229-
} else { Default::default() };
230-
tag.number = tag_number;
231-
tag_number_is_set = true;
232-
tag.into()
233-
}
234-
} else if path.is_ident("simple") {
235-
tag = {
236-
let possibly_with_prefix = lit_str.value();
237-
let without_prefix = possibly_with_prefix.trim_start_matches("0x");
238-
let tag_number = u8::from_str_radix(without_prefix, 16).expect("tag values must be between one and 254");
239-
let mut tag = if let Tag::Simple(tag) = tag {
240-
tag
241-
} else { Default::default() };
242-
tag.0 = tag_number;
243-
tag_number_is_set = true;
244-
tag.into()
245-
};
246-
} else {
247-
panic!("unknown `tlv` attribute for field `{}`: {:?}", name, path);
248-
}
249-
250-
}
251-
other => panic!(
252-
"a malformed `tlv` attribute for field `{}`: {:?}",
253-
name, other
254-
),
154+
attr.parse_nested_meta(|meta| {
155+
let path = meta.path;
156+
if path.is_ident("slice") {
157+
slice = true;
158+
} else if path.is_ident("universal") {
159+
tag = {
160+
let mut tag = if let Tag::Ber(tag) = tag {
161+
tag
162+
} else {
163+
Default::default()
164+
};
165+
tag.class = Class::Universal;
166+
tag.into()
167+
};
168+
} else if path.is_ident("application") {
169+
tag = {
170+
let mut tag = if let Tag::Ber(tag) = tag {
171+
tag
172+
} else {
173+
Default::default()
174+
};
175+
tag.class = Class::Application;
176+
tag.into()
177+
};
178+
} else if path.is_ident("context") {
179+
tag = {
180+
let mut tag = if let Tag::Ber(tag) = tag {
181+
tag
182+
} else {
183+
Default::default()
184+
};
185+
tag.class = Class::Context;
186+
tag.into()
187+
};
188+
} else if path.is_ident("private") {
189+
tag = {
190+
let mut tag = if let Tag::Ber(tag) = tag {
191+
tag
192+
} else {
193+
Default::default()
194+
};
195+
tag.class = Class::Private;
196+
tag.into()
197+
};
198+
} else if path.is_ident("constructed") {
199+
tag = {
200+
let mut tag = if let Tag::Ber(tag) = tag {
201+
tag
202+
} else {
203+
Default::default()
204+
};
205+
tag.constructed = true;
206+
tag.into()
207+
};
208+
} else if path.is_ident("primitive") {
209+
tag = {
210+
let mut tag = if let Tag::Ber(tag) = tag {
211+
tag
212+
} else {
213+
Default::default()
214+
};
215+
tag.constructed = false;
216+
tag.into()
217+
};
218+
} else if path.is_ident("number") {
219+
tag = {
220+
if !meta.input.peek(Token![=]) || !meta.input.peek2(LitStr) {
221+
panic!("Malformed TLV attribute");
255222
}
223+
let _: Token![=] = meta.input.parse().expect("unreachable");
224+
let lit_str: LitStr = meta.input.parse().expect("unreachable");
225+
226+
let possibly_with_prefix = lit_str.value();
227+
let without_prefix = possibly_with_prefix.trim_start_matches("0x");
228+
let tag_number = u16::from_str_radix(without_prefix, 16)
229+
.expect("tag values must be between one and 254");
230+
let mut tag = if let Tag::Ber(tag) = tag {
231+
tag
232+
} else {
233+
Default::default()
234+
};
235+
tag.number = tag_number;
236+
tag_number_is_set = true;
237+
tag.into()
256238
}
239+
} else if path.is_ident("simple") {
240+
tag = {
241+
if !meta.input.peek(Token![=]) || !meta.input.peek2(LitStr) {
242+
panic!("Malformed TLV attribute");
243+
}
244+
let _: Token![=] = meta.input.parse().expect("unreachable");
245+
let lit_str: LitStr = meta.input.parse().expect("unreachable");
246+
247+
let possibly_with_prefix = lit_str.value();
248+
let without_prefix = possibly_with_prefix.trim_start_matches("0x");
249+
let tag_number = u8::from_str_radix(without_prefix, 16)
250+
.expect("tag values must be between one and 254");
251+
let mut tag = if let Tag::Simple(tag) = tag {
252+
tag
253+
} else {
254+
Default::default()
255+
};
256+
tag.0 = tag_number;
257+
tag_number_is_set = true;
258+
tag.into()
259+
};
260+
} else {
261+
panic!("unknown `tlv` attribute for field `{}`: {:?}", name, path);
257262
}
258-
other => panic!(
259-
"malformed `tlv` attribute for field `{}`: {:#?}",
260-
name, other
261-
),
262-
}
263+
Ok(())
264+
})
265+
.unwrap();
266+
267+
// match attr.parse_meta().expect("error parsing `tlv` attribute") {
268+
// Meta::List(MetaList { nested, .. }) if !nested.is_empty() => {
269+
// for entry in nested {
270+
// match entry {
271+
// NestedMeta::Meta(Meta::Path(path)) => {
272+
// if path.is_ident("slice") {
273+
// slice = true;
274+
// } else if path.is_ident("universal") {
275+
// tag = {
276+
// let mut tag = if let Tag::Ber(tag) = tag {
277+
// tag
278+
// } else {
279+
// Default::default()
280+
// };
281+
// tag.class = Class::Universal;
282+
// tag.into()
283+
// };
284+
// } else if path.is_ident("application") {
285+
// tag = {
286+
// let mut tag = if let Tag::Ber(tag) = tag {
287+
// tag
288+
// } else {
289+
// Default::default()
290+
// };
291+
// tag.class = Class::Application;
292+
// tag.into()
293+
// };
294+
// } else if path.is_ident("context") {
295+
// tag = {
296+
// let mut tag = if let Tag::Ber(tag) = tag {
297+
// tag
298+
// } else {
299+
// Default::default()
300+
// };
301+
// tag.class = Class::Context;
302+
// tag.into()
303+
// };
304+
// } else if path.is_ident("private") {
305+
// tag = {
306+
// let mut tag = if let Tag::Ber(tag) = tag {
307+
// tag
308+
// } else {
309+
// Default::default()
310+
// };
311+
// tag.class = Class::Private;
312+
// tag.into()
313+
// };
314+
// } else if path.is_ident("constructed") {
315+
// tag = {
316+
// let mut tag = if let Tag::Ber(tag) = tag {
317+
// tag
318+
// } else {
319+
// Default::default()
320+
// };
321+
// tag.constructed = true;
322+
// tag.into()
323+
// };
324+
// } else if path.is_ident("primitive") {
325+
// tag = {
326+
// let mut tag = if let Tag::Ber(tag) = tag {
327+
// tag
328+
// } else {
329+
// Default::default()
330+
// };
331+
// tag.constructed = false;
332+
// tag.into()
333+
// };
334+
// } else {
335+
// panic!("unknown `tlv` attribute for field `{}`: {:?}", name, path);
336+
// }
337+
// }
338+
// NestedMeta::Meta(Meta::NameValue(MetaNameValue {
339+
// path,
340+
// lit: Lit::Str(lit_str),
341+
// ..
342+
// })) => {
343+
// // Parse the `type = "..."` attribute
344+
// if path.is_ident("number") {
345+
// tag = {
346+
// let possibly_with_prefix = lit_str.value();
347+
// let without_prefix =
348+
// possibly_with_prefix.trim_start_matches("0x");
349+
// let tag_number = u16::from_str_radix(without_prefix, 16)
350+
// .expect("tag values must be between one and 254");
351+
// let mut tag = if let Tag::Ber(tag) = tag {
352+
// tag
353+
// } else {
354+
// Default::default()
355+
// };
356+
// tag.number = tag_number;
357+
// tag_number_is_set = true;
358+
// tag.into()
359+
// }
360+
// } else if path.is_ident("simple") {
361+
// tag = {
362+
// let possibly_with_prefix = lit_str.value();
363+
// let without_prefix =
364+
// possibly_with_prefix.trim_start_matches("0x");
365+
// let tag_number = u8::from_str_radix(without_prefix, 16)
366+
// .expect("tag values must be between one and 254");
367+
// let mut tag = if let Tag::Simple(tag) = tag {
368+
// tag
369+
// } else {
370+
// Default::default()
371+
// };
372+
// tag.0 = tag_number;
373+
// tag_number_is_set = true;
374+
// tag.into()
375+
// };
376+
// } else {
377+
// panic!("unknown `tlv` attribute for field `{}`: {:?}", name, path);
378+
// }
379+
// }
380+
// other => panic!(
381+
// "a malformed `tlv` attribute for field `{}`: {:?}",
382+
// name, other
383+
// ),
384+
// }
385+
// }
386+
// }
387+
// other => panic!(
388+
// "malformed `tlv` attribute for field `{}`: {:#?}",
389+
// name, other
390+
// ),
391+
// }
263392
}
264393

265394
if tag_number_is_set {

0 commit comments

Comments
 (0)