1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#![recursion_limit = "128"]
extern crate proc_macro;
extern crate syn;
#[macro_use] extern crate quote;
use ::{ proc_macro::TokenStream, syn::{ Data, Ident, Fields, DeriveInput } };
#[proc_macro_derive(Asn1Der)]
pub fn asn1_der_derive(input: TokenStream) -> TokenStream {
let input: DeriveInput = syn::parse(input).unwrap();
let s = if let Data::Struct(s) = input.data { s }
else { panic!("Asn1Der supports named structs only") };
let fields: Vec<Ident> = match s.fields {
Fields::Named(fields) => fields.named.into_iter().map(|f| f.ident.unwrap()).collect(),
_ => panic!("Asn1Der supports named structs only")
};
gen_impl(&input.ident, fields)
}
fn gen_impl<'a>(s: &Ident, fields: Vec<Ident>) -> TokenStream {
let (f0, f1, f2) =
(fields.iter(), fields.iter(), fields.iter());
let from = quote! {
impl ::asn1_der::FromDerObject for #s {
fn from_der_object(der_object: ::asn1_der::DerObject)
-> ::std::result::Result<Self, ::asn1_der::Asn1DerError>
{
fn parse_next<T: ::asn1_der::FromDerObject>
(iter: &mut ::std::iter::Iterator<Item = ::asn1_der::DerObject>)
-> ::std::result::Result<T, ::asn1_der::Asn1DerError>
{
let der_object = iter.next()
.ok_or(::asn1_der::Asn1DerError::LengthMismatch)?;
T::from_der_object(der_object)
}
let mut fields =
::std::vec::Vec::<::asn1_der::DerObject>::from_der_object(der_object)?
.into_iter();
let s = Self{ #( #f0: parse_next(&mut fields)?, )* };
if fields.len() > 0 { Err(::asn1_der::Asn1DerError::LengthMismatch) }
else { Ok(s) }
}
}
};
let into = quote! {
impl ::asn1_der::IntoDerObject for #s {
fn into_der_object(self) -> ::asn1_der::DerObject {
let mut objects = ::std::vec::Vec::new();
#( objects.push(self.#f1.into_der_object()); )*
objects.into_der_object()
}
fn serialized_len(&self) -> usize {
let mut len = 0usize;
#( len += self.#f2.serialized_len(); )*
::asn1_der::DerObject::compute_serialized_len(len)
}
}
};
TokenStream::from(quote!( #into #from ))
}