rust-dnsbox/lib/dnsbox-derive/src/dns_packet_data.rs

60 lines
1.9 KiB
Rust
Raw Normal View History

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!{};
2017-12-27 14:24:11 +00:00
let mut serialize_fields = quote!{};
2017-12-16 20:58:18 +00:00
for field in fields {
let field_name = field.ident.as_ref().unwrap();
2017-12-27 14:24:11 +00:00
let parse_ctx_msg = format!("failed parsing field {}::{}", name, field_name);
let serialize_ctx_msg = format!("failed serializing field {}::{}", name, field_name);
2017-12-16 20:58:18 +00:00
parse_fields = quote!{#parse_fields
2017-12-27 14:24:11 +00:00
#field_name: DnsPacketData::deserialize(_data).context(#parse_ctx_msg)?,
};
serialize_fields = quote!{#serialize_fields
self.#field_name.serialize(_context, _packet).context(#serialize_ctx_msg)?;
2017-12-16 20:58:18 +00:00
};
}
quote!{
2017-12-27 14:24:11 +00:00
impl ::dnsbox_base::ser::packet::DnsPacketData for #name {
2017-12-16 20:58:18 +00:00
#[allow(unused_imports)]
2019-07-01 15:43:34 +00:00
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::packet::DnsPacketData;
2017-12-16 20:58:18 +00:00
Ok(#name{ #parse_fields })
}
2017-12-27 14:24:11 +00:00
#[allow(unused_imports)]
fn serialize(&self, _context: &mut ::dnsbox_base::ser::packet::DnsPacketWriteContext, _packet: &mut Vec<u8>) -> ::dnsbox_base::errors::Result<()> {
2019-07-01 15:43:34 +00:00
use dnsbox_base::_failure::ResultExt;
use dnsbox_base::ser::packet::DnsPacketData;
2017-12-27 14:24:11 +00:00
#serialize_fields
Ok(())
}
2017-12-16 20:58:18 +00:00
}
}
}