abomonation_derive/
lib.rs

1#![recursion_limit="128"]
2
3use synstructure::decl_derive;
4use quote::quote;
5
6decl_derive!([Abomonation, attributes(unsafe_abomonate_ignore)] => derive_abomonation);
7
8fn derive_abomonation(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
9    s.filter(|bi| {
10        !bi.ast().attrs.iter()
11            .map(|attr| attr.parse_meta())
12            .filter_map(Result::ok)
13            .any(|attr| attr.path().is_ident("unsafe_abomonate_ignore"))
14    });
15
16    let entomb = s.each(|bi| quote! {
17        ::abomonation::Abomonation::entomb(#bi, _write)?;
18    });
19
20    let extent = s.each(|bi| quote! {
21        sum += ::abomonation::Abomonation::extent(#bi);
22    });
23
24    s.bind_with(|_| synstructure::BindStyle::RefMut);
25
26    let exhume = s.each(|bi| quote! {
27        let temp = bytes;
28        bytes = ::abomonation::Abomonation::exhume(#bi, temp)?;
29    });
30
31    s.bound_impl(quote!(abomonation::Abomonation), quote! {
32        #[inline] unsafe fn entomb<W: ::std::io::Write>(&self, _write: &mut W) -> ::std::io::Result<()> {
33            match *self { #entomb }
34            Ok(())
35        }
36        #[allow(unused_mut)]
37        #[inline] fn extent(&self) -> usize {
38            let mut sum = 0;
39            match *self { #extent }
40            sum
41        }
42        #[allow(unused_mut)]
43        #[inline] unsafe fn exhume<'a,'b>(
44            &'a mut self,
45            mut bytes: &'b mut [u8]
46        ) -> Option<&'b mut [u8]> {
47            match *self { #exhume }
48            Some(bytes)
49        }
50    })
51}