serde-inline-default 1.0.1

Serde default values via inline declaration
Documentation
use quote::quote;
use syn::{spanned::Spanned, Error, Fields, ItemEnum, ItemStruct};

use crate::utils::{check_field_for_default_expr, ATTR_NAME, DEFAULT_FN_PREFIX};

pub(crate) fn expand_struct(mut item: ItemStruct) -> proc_macro::TokenStream {
    let mut default_fns = vec![];

    for (i, field) in item.fields.iter_mut().enumerate() {
        default_fns.extend(check_field_for_default_expr(field, || {
            format!("{}_{}_Field{}", DEFAULT_FN_PREFIX, item.ident, i)
        }));
    }

    quote! {
        #( #default_fns )*

        #item
    }
    .into()
}

pub(crate) fn expand_enum(mut item: ItemEnum) -> proc_macro::TokenStream {
    let mut default_fns = vec![];

    for (i, variant) in item.variants.iter_mut().enumerate() {
        if variant.attrs.iter().any(|a| a.path().is_ident(ATTR_NAME)) {
            return Error::new(
                variant.span(),
                format!(
                    "#[{}] can only be used on named enum variant fields",
                    ATTR_NAME
                ),
            )
            .to_compile_error()
            .into();
        }

        let fields = match &mut variant.fields {
            Fields::Named(fields) => fields,
            _ => {
                return Error::new(
                    variant.span(),
                    format!(
                        "#[{}] can only be used on named enum variant fields",
                        ATTR_NAME
                    ),
                )
                .to_compile_error()
                .into()
            }
        };

        for (j, field) in fields.named.iter_mut().enumerate() {
            default_fns.extend(check_field_for_default_expr(field, || {
                format!(
                    "{}_{}_Variant{}_Field{}",
                    DEFAULT_FN_PREFIX, item.ident, i, j
                )
            }));
        }
    }

    quote! {
        #( #default_fns )*

        #item
    }
    .into()
}