in avro_derive/src/lib.rs [114:204]
fn get_data_struct_schema_def(
full_schema_name: &str,
record_doc: Option<String>,
aliases: Vec<String>,
s: &syn::DataStruct,
error_span: Span,
) -> Result<TokenStream, Vec<syn::Error>> {
let mut record_field_exprs = vec![];
match s.fields {
syn::Fields::Named(ref a) => {
let mut index: usize = 0;
for field in a.named.iter() {
let mut name = field.ident.as_ref().unwrap().to_string(); // we know everything has a name
if let Some(raw_name) = name.strip_prefix("r#") {
name = raw_name.to_string();
}
let field_attrs =
FieldOptions::from_attributes(&field.attrs[..]).map_err(darling_to_syn)?;
let doc =
preserve_optional(field_attrs.doc.or_else(|| extract_outer_doc(&field.attrs)));
if let Some(rename) = field_attrs.rename {
name = rename
}
if let Some(true) = field_attrs.skip {
continue;
}
let default_value = match field_attrs.default {
Some(default_value) => {
let _: serde_json::Value = serde_json::from_str(&default_value[..])
.map_err(|e| {
vec![syn::Error::new(
field.ident.span(),
format!("Invalid avro default json: \n{e}"),
)]
})?;
quote! {
Some(serde_json::from_str(#default_value).expect(format!("Invalid JSON: {:?}", #default_value).as_str()))
}
}
None => quote! { None },
};
let aliases = preserve_vec(field_attrs.alias);
let schema_expr = type_to_schema_expr(&field.ty)?;
let position = index;
record_field_exprs.push(quote! {
apache_avro::schema::RecordField {
name: #name.to_string(),
doc: #doc,
default: #default_value,
aliases: #aliases,
schema: #schema_expr,
order: apache_avro::schema::RecordFieldOrder::Ascending,
position: #position,
custom_attributes: Default::default(),
}
});
index += 1;
}
}
syn::Fields::Unnamed(_) => {
return Err(vec![syn::Error::new(
error_span,
"AvroSchema derive does not work for tuple structs",
)])
}
syn::Fields::Unit => {
return Err(vec![syn::Error::new(
error_span,
"AvroSchema derive does not work for unit structs",
)])
}
}
let record_doc = preserve_optional(record_doc);
let record_aliases = preserve_vec(aliases);
Ok(quote! {
let schema_fields = vec![#(#record_field_exprs),*];
let name = apache_avro::schema::Name::new(#full_schema_name).expect(&format!("Unable to parse struct name for schema {}", #full_schema_name)[..]);
let lookup: std::collections::BTreeMap<String, usize> = schema_fields
.iter()
.map(|field| (field.name.to_owned(), field.position))
.collect();
apache_avro::schema::Schema::Record(apache_avro::schema::RecordSchema {
name,
aliases: #record_aliases,
doc: #record_doc,
fields: schema_fields,
lookup,
attributes: Default::default(),
})
})
}