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

57 lines
1.7 KiB
Rust
Raw Normal View History

2017-12-21 12:32:14 +00:00
use syn;
use quote;
pub fn build(ast: &syn::DeriveInput) -> quote::Tokens {
let fields = match ast.body {
syn::Body::Enum(_) => panic!("Deriving DnsTextData not supported for enum types"),
syn::Body::Struct(syn::VariantData::Struct(ref s)) => s,
syn::Body::Struct(_) => panic!("Deriving DnsTextData not supported for unit / tuple struct types"),
};
if !ast.generics.ty_params.is_empty() {
panic!("Type parameters not supported for deriving DnsTextData");
}
if !ast.generics.where_clause.predicates.is_empty() {
panic!("Where clauses not supported for deriving DnsTextData");
}
if !ast.generics.lifetimes.is_empty() {
panic!("Lifetimes not supported for deriving DnsTextData");
}
let name = &ast.ident;
let mut parse_fields = quote!{};
let mut format_fields = quote!{};
for field in fields {
let field_name = field.ident.as_ref().unwrap();
parse_fields = quote!{#parse_fields
2017-12-26 21:23:51 +00:00
#field_name: DnsTextData::dns_parse(_context, _data).with_context(|_| format!("failed parsing field {}::{}", stringify!(#name), stringify!(#field_name)))?,
2017-12-21 12:32:14 +00:00
};
format_fields = quote!{#format_fields
DnsTextData::dns_format(&self.#field_name, f)?;
};
}
quote!{
#[allow(unused_imports)]
2017-12-27 14:24:11 +00:00
impl ::dnsbox_base::ser::text::DnsTextData for #name {
2017-12-26 21:23:51 +00:00
fn dns_parse(_context: &::dnsbox_base::ser::text::DnsTextContext, _data: &mut &str) -> ::dnsbox_base::errors::Result<Self> {
2017-12-21 12:32:14 +00:00
use dnsbox_base::failure::ResultExt;
2017-12-27 14:24:11 +00:00
use dnsbox_base::ser::text::DnsTextData;
2017-12-21 12:32:14 +00:00
Ok(#name{ #parse_fields })
}
fn dns_format(&self, f: &mut ::dnsbox_base::ser::text::DnsTextFormatter) -> ::std::fmt::Result {
2017-12-27 14:24:11 +00:00
use dnsbox_base::ser::text::DnsTextData;
2017-12-21 12:32:14 +00:00
use std::fmt::{self, Write};
#format_fields
Ok(())
}
}
}
}