Skip to content

Commit 9af7668

Browse files
committed
Add structs.merge
1 parent 471f368 commit 9af7668

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

docs/structs_doc.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,31 @@
22

33
Skylib module containing functions that operate on structs.
44

5+
<a id="structs.merge"></a>
6+
7+
## structs.merge
8+
9+
<pre>
10+
load("@bazel_skylib//lib:structs.bzl", "structs")
11+
12+
structs.merge(<a href="#structs.merge-first">first</a>, <a href="#structs.merge-rest">*rest</a>)
13+
</pre>
14+
15+
Merges multiple `struct` instances together. Later `struct` keys overwrite early `struct` keys.
16+
17+
**PARAMETERS**
18+
19+
20+
| Name | Description | Default Value |
21+
| :------------- | :------------- | :------------- |
22+
| <a id="structs.merge-first"></a>first | The initial `struct` to merge keys/values into. | none |
23+
| <a id="structs.merge-rest"></a>rest | Other `struct` instances to merge. | none |
24+
25+
**RETURNS**
26+
27+
A merged `struct`.
28+
29+
530
<a id="structs.to_dict"></a>
631

732
## structs.to_dict

lib/structs.bzl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,22 @@ def _to_dict(s):
3434
if key != "to_json" and key != "to_proto"
3535
}
3636

37+
def _merge(first, *rest):
38+
"""Merges multiple `struct` instances together. Later `struct` keys overwrite early `struct` keys.
39+
40+
Args:
41+
first: The initial `struct` to merge keys/values into.
42+
*rest: Other `struct` instances to merge.
43+
44+
Returns:
45+
A merged `struct`.
46+
"""
47+
map = _to_dict(first)
48+
for r in rest:
49+
map |= _to_dict(r)
50+
return struct(**map)
51+
3752
structs = struct(
3853
to_dict = _to_dict,
54+
merge = _merge,
3955
)

tests/structs_tests.bzl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,33 @@ def _add_test(ctx):
4646

4747
add_test = unittest.make(_add_test)
4848

49+
def _merge_test(ctx):
50+
"""Unit tests for structs.merge."""
51+
env = unittest.begin(ctx)
52+
53+
# Fixtures
54+
a = struct(a = 1)
55+
b = struct(b = 2)
56+
c = struct(a = 3)
57+
58+
# Test one argument
59+
asserts.equals(env, {"a": 1}, structs.to_dict(structs.merge(a)))
60+
61+
# Test two arguments
62+
asserts.equals(env, {"a": 1}, structs.to_dict(structs.merge(a, a)))
63+
asserts.equals(env, {"a": 1, "b": 2}, structs.to_dict(structs.merge(a, b)))
64+
65+
# Test overwrite
66+
asserts.equals(env, {"a": 3}, structs.to_dict(structs.merge(a, c)))
67+
68+
return unittest.end(env)
69+
70+
merge_test = unittest.make(_merge_test)
71+
4972
def structs_test_suite():
5073
"""Creates the test targets and test suite for structs.bzl tests."""
5174
unittest.suite(
5275
"structs_tests",
5376
add_test,
77+
merge_test,
5478
)

0 commit comments

Comments
 (0)