fn derive_chrony_serialize_struct()

in chrony-candm-derive/src/lib.rs [25:76]


fn derive_chrony_serialize_struct(name: proc_macro2::Ident, ds: syn::DataStruct) -> TokenStream {
    let mut length = quote!(0usize);
    let mut serialize = quote!();
    let mut deserialize = quote!();

    for field in ds.fields.iter() {
        let ty = &field.ty;
        let ident = field
            .ident
            .as_ref()
            .expect("Deriving ChronySerialize for tuple structs is not supported.");
        let pad = parse_pad_attr(field.attrs.as_ref());
        length
            .extend(quote! { + <#ty as ::chrony_candm::common::ChronySerialize>::length() + #pad });
        serialize.extend(quote! {
            ::chrony_candm::common::ChronySerialize::serialize(&self.#ident, buf);
            if #pad != 0 {
                buf.put_bytes(0, #pad)
            }
        });
        deserialize.extend(quote! {
            #ident: {
                let field = <#ty as ::chrony_candm::common::ChronySerialize>::deserialize_unchecked(buf)?;
                if #pad != 0 {
                    buf.advance(#pad)
                }
                field
            },
        })
    }

    let expanded = quote! {
        impl ::chrony_candm::common::ChronySerialize for #name {
            fn length() -> usize {
                #length
            }

            fn serialize<B: ::bytes::BufMut>(&self, buf: &mut B) {
                #serialize
            }

            fn deserialize_unchecked<B: ::bytes::Buf>(buf: &mut B) -> ::std::result::Result<Self, ::chrony_candm::common::DeserializationError> {
                ::std::result::Result::Ok(#name {
                    #deserialize
                })
            }

        }
    };

    TokenStream::from(expanded)
}