in chrony-candm-derive/src/lib.rs [78:119]
fn derive_chrony_serialize_enum(
name: proc_macro2::Ident,
attrs: &[syn::Attribute],
_ds: syn::DataEnum,
) -> TokenStream {
let repr = attrs
.iter()
.find_map(|attr| {
if let syn::Meta::List(meta_list) = attr.parse_meta().ok()? {
if meta_list.path.get_ident()? == "repr" {
let repr = meta_list.nested.iter().next()?;
let repr: syn::Ident = parse_quote! { #repr };
Some(repr)
} else {
None
}
} else {
None
}
})
.expect("Must specify a #[repr] attribute to derive ChronySerialize for an enum.");
let expanded = quote! {
impl ::chrony_candm::common::ChronySerialize for #name {
fn length() -> usize {
::std::mem::size_of::<#repr>()
}
fn serialize<B: ::bytes::BufMut>(&self, buf: &mut B) {
buf.put_slice((&<#repr>::from(*self).to_be_bytes()) as &[u8]);
}
fn deserialize_unchecked<B: ::bytes::Buf>(buf: &mut B) -> ::std::result::Result<Self, ::chrony_candm::common::DeserializationError> {
let mut dst = [0u8; ::std::mem::size_of::<#repr>()];
buf.copy_to_slice(&mut dst);
<Self as ::std::convert::TryFrom<#repr>>::try_from(<#repr>::from_be_bytes(dst)).map_err(|_| ::chrony_candm::common::DeserializationError::new("value outside of enum range"))
}
}
};
TokenStream::from(expanded)
}