in src/descriptors/struct_desc.rs [40:81]
fn generate_deserializer(&self) -> proc_macro2::TokenStream {
let mut versioned_deserializers = proc_macro2::TokenStream::new();
let struct_ident = format_ident!("{}", self.ty);
for i in 1..=self.version {
let mut versioned_deserializer = proc_macro2::TokenStream::new();
let mut semantic_deserializer = proc_macro2::TokenStream::new();
// Generate field and semantic deserializers for all fields.
// Not all fields have semantic deserializers defined and some fields
// might be missing in version `i`. In these cases the generate_deserializer() and
// generate_semantic_deserializer() will return an empty token stream.
for field in &self.fields {
versioned_deserializer.extend(field.generate_deserializer(i));
semantic_deserializer.extend(field.generate_semantic_deserializer(i));
}
// Generate the match arm for version `i`.
//
// The semantic deserialization functions will be called after the object is constructed
// using the previously generated field deserializers.
versioned_deserializers.extend(quote! {
#i => {
let mut object = #struct_ident {
#versioned_deserializer
};
#semantic_deserializer
Ok(object)
}
});
}
// Generate code to map the app version to struct version and wrap the
// deserializers with the `version` match.
quote! {
let version = version_map.get_type_version(app_version, <Self as Versionize>::type_id());
match version {
#versioned_deserializers
_ => panic!("Unknown {:?} version {}.", <Self as Versionize>::type_id(), version)
}
}
}