fn get_data_struct_schema_def()

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(),
        })
    })
}