config-rs icon indicating copy to clipboard operation
config-rs copied to clipboard

Merging of arrays

Open vorner opened this issue 6 years ago • 5 comments

Is there a way to merge two arrays by appending them instead of overwriting one with the other? Or how are sets that should be merged usually represented?

By the way, I had to try it out, this behaviour wasn't clear from the documentation.

vorner avatar Mar 23 '18 17:03 vorner

I'd agree documentation could be improved here.


I'm not sure how to support "merging" arrays and still allow "replacing" arrays (which I consider more common).

Perhaps a method that flags a config property as a "merge-able" array?

config.set_array_merge_behavior("x.y.z", MergeBehavior::AppendUnique);

Very rough name. Welcome to a good suggestion there.

mehcode avatar Jul 02 '18 22:07 mehcode

Thinking about that, it's probably the user that should be able to choose if to merge or replace them somehow ‒ it doesn't really make sense to make some arrays mergeable and some replaceable (especially not in the same application, that could lead to a lot of confusion). But replace vs. merge would like need some kind of support from the actual format/config language and I'm not aware of any :-(.

vorner avatar Jul 05 '18 17:07 vorner

HOCON allows you to concatenate arrays with syntax like key=${key} [1, 2, 3], but that is transparent from the applications perspective.

tmccombs avatar Jul 05 '18 21:07 tmccombs

Thought about this recently. I'd like to be able to do this:

config.set_array_merge_strategy(MergeStrategy::Replace); // Default

// ---

enum MergeStrategy {
  Replace,
  Append,
  AppendUnique,
}

I agree that per-key seems like too much. Specific formats could support that on their own (like HOCON if/when we add that).

mehcode avatar Oct 05 '18 06:10 mehcode

I would like to use array merging and just finished implementing a solution in my own fork.

Implementing the actual merging wasn't that much of an issue, but to contribute this improvement to your repo, I'm really unsure how I should implement the configurability. We could quite easily add an array_merge_strategy field to the Config struct, but the actual merging is performed by the Expression enum, which is created by the set_value function in src/source.rs, which is called by the collect_to method of the Source trait. My point is, the information about which merge strategy to use needs to traverse several layers of abstraction, and I need some help with determining how to do this in the most proper way, without breaking too many established APIs.

sigurdo avatar Nov 10 '23 12:11 sigurdo