use proc_macro2::TokenStream;
use quote::quote;
use super::guards::generate_non_object_guard;
pub(super) struct FinishCollectionTokens<'a> {
pub append_destructured: &'a [TokenStream],
pub map_destructured: &'a [TokenStream],
pub append_inserts: &'a [TokenStream],
pub map_inserts: &'a [TokenStream],
}
pub(super) fn merge_layer_tokens(
config_ident: &syn::Ident,
krate: &TokenStream,
map_merge_logic: &[TokenStream],
append_merge_logic: &[TokenStream],
) -> TokenStream {
let non_object_guard = generate_non_object_guard(config_ident, krate);
quote! {
let provenance = layer.provenance();
let path = layer.path().map(|p| p.to_owned());
let value = layer.into_value();
let mut map = match value {
#krate::serde_json::Value::Object(map) => map,
other => { #non_object_guard }
};
#( #map_merge_logic )*
#( #append_merge_logic )*
if !map.is_empty() {
#krate::declarative::merge_value(
&mut self.value,
#krate::serde_json::Value::Object(map),
);
}
Ok(())
}
}
pub(super) fn finish_tokens(
state_ident: &syn::Ident,
krate: &TokenStream,
collections: &FinishCollectionTokens<'_>,
) -> TokenStream {
let append_destructured = collections.append_destructured;
let map_destructured = collections.map_destructured;
let append_inserts = collections.append_inserts;
let map_inserts = collections.map_inserts;
quote! {
let #state_ident {
mut value,
#( #append_destructured, )*
#( #map_destructured, )*
} = self;
let mut overlay = #krate::serde_json::Map::new();
#( #append_inserts )*
#( #map_inserts )*
if !overlay.is_empty() {
#krate::declarative::merge_value(
&mut value,
#krate::serde_json::Value::Object(overlay),
);
}
#krate::declarative::from_value_merge(value)
}
}