2017-12-16 20:58:18 +00:00
|
|
|
use syn;
|
|
|
|
use quote;
|
|
|
|
|
2017-12-21 12:32:14 +00:00
|
|
|
pub fn build(ast: &syn::DeriveInput) -> quote::Tokens {
|
2017-12-16 20:58:18 +00:00
|
|
|
let fields = match ast.body {
|
|
|
|
syn::Body::Enum(_) => panic!("Deriving DnsPacketData not supported for enum types"),
|
|
|
|
syn::Body::Struct(syn::VariantData::Struct(ref s)) => s,
|
|
|
|
syn::Body::Struct(_) => panic!("Deriving DnsPacketData not supported for unit / tuple struct types"),
|
|
|
|
};
|
|
|
|
|
|
|
|
if !ast.generics.ty_params.is_empty() {
|
|
|
|
panic!("Type parameters not supported for deriving DnsPacketData");
|
|
|
|
}
|
|
|
|
|
|
|
|
if !ast.generics.where_clause.predicates.is_empty() {
|
|
|
|
panic!("Where clauses not supported for deriving DnsPacketData");
|
|
|
|
}
|
|
|
|
|
|
|
|
if !ast.generics.lifetimes.is_empty() {
|
|
|
|
panic!("Lifetimes not supported for deriving DnsPacketData");
|
|
|
|
}
|
|
|
|
|
|
|
|
let name = &ast.ident;
|
|
|
|
|
|
|
|
let mut parse_fields = quote!{};
|
|
|
|
for field in fields {
|
|
|
|
let field_name = field.ident.as_ref().unwrap();
|
2017-12-21 12:32:14 +00:00
|
|
|
let ctx_msg = format!("failed parsing field {}::{}", stringify!(#name), stringify!(#field_name));
|
2017-12-16 20:58:18 +00:00
|
|
|
|
|
|
|
parse_fields = quote!{#parse_fields
|
2017-12-21 12:32:14 +00:00
|
|
|
#field_name: DnsPacketData::deserialize(_data).context(#ctx_msg)?,
|
2017-12-16 20:58:18 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
quote!{
|
|
|
|
impl ::dnsbox_base::ser::DnsPacketData for #name {
|
|
|
|
#[allow(unused_imports)]
|
|
|
|
fn deserialize(_data: &mut ::std::io::Cursor<::dnsbox_base::bytes::Bytes>) -> ::dnsbox_base::errors::Result<Self> {
|
|
|
|
use ::dnsbox_base::failure::ResultExt;
|
|
|
|
use ::dnsbox_base::ser::DnsPacketData;
|
|
|
|
Ok(#name{ #parse_fields })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|