File tree Expand file tree Collapse file tree 2 files changed +47
-1
lines changed Expand file tree Collapse file tree 2 files changed +47
-1
lines changed Original file line number Diff line number Diff line change @@ -861,7 +861,12 @@ auto JSON::clear_except(std::initializer_list<JSON::String> keys) -> void {
861
861
auto JSON::merge (const JSON::Object &other) -> void {
862
862
assert (this ->is_object ());
863
863
for (const auto &pair : other) {
864
- this ->assign (pair.first , pair.second );
864
+ const auto maybe_key{this ->try_at (pair.first , pair.hash )};
865
+ if (maybe_key && maybe_key->is_object () && pair.second .is_object ()) {
866
+ this ->at (pair.first , pair.hash ).merge (pair.second .as_object ());
867
+ } else {
868
+ this ->assign (pair.first , pair.second );
869
+ }
865
870
}
866
871
}
867
872
Original file line number Diff line number Diff line change @@ -780,6 +780,47 @@ TEST(JSON_object, merge_with_overlap) {
780
780
EXPECT_EQ (document.at (" baz" ).to_integer (), 9 );
781
781
}
782
782
783
+ TEST (JSON_object, merge_deep_object) {
784
+ auto document{sourcemeta::core::parse_json (R"JSON( {
785
+ "foo": {
786
+ "bar": {
787
+ "baz": 1,
788
+ "array": [ { "x": 1 } ]
789
+ }
790
+ },
791
+ "x": true
792
+ })JSON" )};
793
+
794
+ const auto other{sourcemeta::core::parse_json (R"JSON( {
795
+ "foo": {
796
+ "bar": {
797
+ "qux": 2,
798
+ "array": [ { "y": 2 }, 2, 3 ]
799
+ }
800
+ },
801
+ "x": {
802
+ "y": 1
803
+ }
804
+ })JSON" )};
805
+
806
+ document.merge (other.as_object ());
807
+
808
+ const auto expected{sourcemeta::core::parse_json (R"JSON( {
809
+ "foo": {
810
+ "bar": {
811
+ "baz": 1,
812
+ "qux": 2,
813
+ "array": [ { "y": 2 }, 2, 3 ]
814
+ }
815
+ },
816
+ "x": {
817
+ "y": 1
818
+ }
819
+ })JSON" )};
820
+
821
+ EXPECT_EQ (document, expected);
822
+ }
823
+
783
824
TEST (JSON_object, at_or_defined) {
784
825
const sourcemeta::core::JSON document{{" foo" , sourcemeta::core::JSON{true }},
785
826
{" bar" , sourcemeta::core::JSON{1 }}};
You can’t perform that action at this time.
0 commit comments