Skip to content

feat: add pluggable slice merge strategies - #432

Open
donejeh wants to merge 1 commit into
knadh:masterfrom
donejeh:feat/slice-merge-strategies
Open

donejeh wants to merge 1 commit into
knadh:masterfrom
donejeh:feat/slice-merge-strategies

Conversation

@donejeh

@donejeh donejeh commented Jul 25, 2026

Copy link
Copy Markdown

Merge overwrites slices wholesale, so anyone who wants a later config layer to add
to a list rather than replace it has to write a WithMergeFunc from scratch and
reimplement the deep merge around it. This adds three ready-made strategies to the
maps package and exposes each one as a Load option.

  • MergeAppendSlices concatenates the source slice after the destination one.
  • MergeByIndex pairs elements at the same index, deep-merging maps and recursing
    into nested slices.
  • MergeByKey(field) matches map elements on a named field, deep-merging the ones
    that match and appending the ones that do not. When a field value repeats on the
    destination side, the first element wins. An empty field name returns an error.

All three keep the existing behaviour for nested maps and non-slice values, and they
handle concrete slice types such as []string rather than only []any. Values taken
from the source are deep-copied, so mutating the source after a merge cannot reach
into the merged result.

WithMergeAppendSlices(), WithMergeByIndex() and WithMergeByKey(field) wire these
into Load. Tests cover both the maps functions directly and the Load options
end to end.

One note on module ordering: the Load options live in the root module but call into
the maps module, which the workspace resolves locally. Releasing the root module
would need a maps tag first. Happy to split this into a maps-only PR and a
follow-up for the Load options if you'd prefer that sequencing.

Merge overwrites slices wholesale, so anyone who wants layered config to add
to a list instead of replacing it has to write a WithMergeFunc from scratch and
reimplement the deep merge around it. This adds three ready made strategies in
the maps package and exposes each one as a Load option.

MergeAppendSlices concatenates the source slice after the destination one.
MergeByIndex pairs elements at the same index, deep merging maps and recursing
into nested slices. MergeByKey matches map elements on a named field, deep
merging the ones that match and appending the ones that do not, with the first
destination element winning when a field value repeats.

All three keep the existing behaviour for nested maps and non slice values, and
handle concrete slice types such as []string rather than only []any. Values
taken from the source are deep copied, so mutating the source after a merge
cannot reach into the merged result.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant