rust/treefile: Use macros to reduce redundancy in treefile merging

On the plus side, when submitting a patch to Github, no one knows
how long it took you to figure out...

Anyways so this reduces redundancy.  I double-checked the list.
I was inspired to pick this back up after seeing a Rust code
snippet somewhere noting that macros defined inside a function
can capture variables, which simplifies this even more.

Closes: #1631
Approved by: jlebon
This commit is contained in:
Colin Walters 2018-10-04 09:43:10 -04:00 committed by Atomic Bot
parent 6583a557ae
commit f1fa436c8a

View File

@ -206,50 +206,52 @@ fn merge_vec_field<T>(dest: &mut Option<Vec<T>>, src: &mut Option<Vec<T>>) {
} }
} }
/// Given two configs, merge them. Ideally we'd do some macro magic and avoid /// Given two configs, merge them.
/// listing all of the fields again.
fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) { fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
merge_basic_field(&mut dest.treeref, &mut src.treeref); macro_rules! merge_basics {
merge_basic_field(&mut dest.rojig, &mut src.rojig); ( $($field:ident),* ) => {{
merge_vec_field(&mut dest.repos, &mut src.repos); $( merge_basic_field(&mut dest.$field, &mut src.$field); )*
merge_basic_field(&mut dest.selinux, &mut src.selinux); }};
merge_basic_field(&mut dest.gpg_key, &mut src.gpg_key); };
merge_basic_field(&mut dest.include, &mut src.include); macro_rules! merge_vecs {
merge_vec_field(&mut dest.packages, &mut src.packages); ( $($field:ident),* ) => {{
merge_basic_field(&mut dest.recommends, &mut src.recommends); $( merge_vec_field(&mut dest.$field, &mut src.$field); )*
merge_basic_field(&mut dest.documentation, &mut src.documentation); }};
merge_vec_field(&mut dest.install_langs, &mut src.install_langs); };
merge_vec_field(&mut dest.initramfs_args, &mut src.initramfs_args);
merge_basic_field(&mut dest.boot_location, &mut src.boot_location); merge_basics!(
merge_basic_field(&mut dest.tmp_is_dir, &mut src.tmp_is_dir); treeref,
merge_basic_field(&mut dest.default_target, &mut src.default_target); rojig,
merge_vec_field(&mut dest.units, &mut src.units); selinux,
merge_basic_field(&mut dest.machineid_compat, &mut src.machineid_compat); gpg_key,
merge_basic_field(&mut dest.releasever, &mut src.releasever); include,
merge_basic_field( recommends,
&mut dest.automatic_version_prefix, documentation,
&mut src.automatic_version_prefix, boot_location,
tmp_is_dir,
default_target,
machineid_compat,
releasever,
automatic_version_prefix,
mutate_os_release,
etc_group_members,
preserve_passwd,
check_passwd,
check_groups,
ignore_removed_users,
ignore_removed_groups,
postprocess_script
); );
merge_basic_field(&mut dest.mutate_os_release, &mut src.mutate_os_release); merge_vecs!(
merge_basic_field(&mut dest.etc_group_members, &mut src.etc_group_members); repos,
merge_basic_field(&mut dest.preserve_passwd, &mut src.preserve_passwd); packages,
merge_basic_field(&mut dest.check_passwd, &mut src.check_passwd); install_langs,
merge_basic_field(&mut dest.check_groups, &mut src.check_groups); initramfs_args,
merge_basic_field( units,
&mut dest.ignore_removed_users, postprocess,
&mut src.ignore_removed_users, add_files,
); remove_files,
merge_basic_field( remove_from_packages
&mut dest.ignore_removed_groups,
&mut src.ignore_removed_groups,
);
merge_basic_field(&mut dest.postprocess_script, &mut src.postprocess_script);
merge_vec_field(&mut dest.postprocess, &mut src.postprocess);
merge_vec_field(&mut dest.add_files, &mut src.add_files);
merge_vec_field(&mut dest.remove_files, &mut src.remove_files);
merge_vec_field(
&mut dest.remove_from_packages,
&mut src.remove_from_packages,
); );
} }