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
extern crate syn; #[macro_use] extern crate synstructure; #[macro_use] extern crate quote; decl_derive!([Abomonation, attributes(unsafe_abomonate_ignore)] => derive_abomonation); fn derive_abomonation(mut s: synstructure::Structure) -> quote::Tokens { s.filter(|bi| !bi.ast().attrs.iter().any(|attr| attr.name() == "unsafe_abomonate_ignore")); let entomb = s.each(|bi| quote! { ::abomonation::Abomonation::entomb(#bi, _write)?; }); let extent = s.each(|bi| quote! { sum += ::abomonation::Abomonation::extent(#bi); }); s.bind_with(|_| synstructure::BindStyle::RefMut); let exhume = s.each(|bi| quote! { let temp = bytes; bytes = ::abomonation::Abomonation::exhume(#bi, temp)?; }); s.bound_impl("::abomonation::Abomonation", quote! { #[inline] unsafe fn entomb<W: ::std::io::Write>(&self, _write: &mut W) -> ::std::io::Result<()> { match *self { #entomb } Ok(()) } #[allow(unused_mut)] #[inline] fn extent(&self) -> usize { let mut sum = 0; match *self { #extent } sum } #[allow(unused_mut)] #[inline] unsafe fn exhume<'a,'b>( &'a mut self, mut bytes: &'b mut [u8] ) -> Option<&'b mut [u8]> { match *self { #exhume } Some(bytes) } }) }