microsandbox_types_macros/lib.rs
1//! Derive macros for presence-aware microsandbox configuration patches.
2
3use proc_macro::TokenStream;
4use syn::{DeriveInput, parse_macro_input};
5
6mod config_patch;
7
8//--------------------------------------------------------------------------------------------------
9// Macros
10//--------------------------------------------------------------------------------------------------
11
12/// Generate a sparse typed patch alongside a named configuration struct.
13///
14/// Use `#[config_patch(name = CustomPatch)]` on the struct to override the generated patch name.
15/// Fields marked `#[config_patch(nested)]` recursively use the patch generated for their type,
16/// including optional nested structs. Updating an absent optional nested value starts from its
17/// default. Fields marked `#[config_patch(merge)]` use [`std::iter::Extend`] semantics, while
18/// `#[config_patch(merge_with = path)]` delegates to a function taking `(&mut T, T)`. Merge fields
19/// also expose `replace_*` methods. Every field exposes `clear_*`, which removes that pending change
20/// from the patch without changing the target. Other fields are atomic: absence leaves the target
21/// unchanged and presence replaces the field, including vectors and maps.
22#[proc_macro_derive(ConfigPatch, attributes(config_patch))]
23pub fn derive_config_patch(input: TokenStream) -> TokenStream {
24 config_patch::expand_config_patch(parse_macro_input!(input as DeriveInput))
25 .unwrap_or_else(syn::Error::into_compile_error)
26 .into()
27}