Skip to content

Commit 9d98b03

Browse files
committed
Create NestedSet to populate set branches along with the leaves
1 parent 9f9c770 commit 9d98b03

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

fieldpath/set.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,23 @@ func (s *Set) RecursiveDifference(s2 *Set) *Set {
110110
}
111111
}
112112

113+
// NestedSet returns a Set that contains all the fields in s, as well as
114+
// all the branches that are typically not included. For example, a set
115+
// made of "a.b.c" will end-up also owning "a" and "a.b".
116+
func (s *Set) NestedSet() *Set {
117+
members := PathElementSet{
118+
members: make(sortedPathElements, 0, s.Members.Size()+len(s.Children.members)),
119+
}
120+
members.members = append(members.members, s.Members.members...)
121+
for _, node := range s.Children.members {
122+
members.Insert(node.pathElement)
123+
}
124+
return &Set{
125+
Members: members,
126+
Children: *s.Children.NestedSet(),
127+
}
128+
}
129+
113130
// Size returns the number of members of the set.
114131
func (s *Set) Size() int {
115132
return s.Members.Size() + s.Children.Size()
@@ -391,6 +408,21 @@ func (s *SetNodeMap) RecursiveDifference(s2 *Set) *SetNodeMap {
391408
return out
392409
}
393410

411+
// NestedSet returns a set that contains all the branches on top of the leaves.
412+
func (s *SetNodeMap) NestedSet() *SetNodeMap {
413+
out := make(sortedSetNode, 0, s.Size())
414+
for _, member := range s.members {
415+
out = append(out, setNode{
416+
pathElement: member.pathElement,
417+
set: member.set.NestedSet(),
418+
})
419+
}
420+
421+
return &SetNodeMap{
422+
members: out,
423+
}
424+
}
425+
394426
// Iterate calls f for each PathElement in the set.
395427
func (s *SetNodeMap) Iterate(f func(PathElement)) {
396428
for _, n := range s.members {

fieldpath/set_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,46 @@ func TestSetDifference(t *testing.T) {
541541
}
542542
}
543543

544+
func TestSetNested(t *testing.T) {
545+
table := []struct {
546+
set, expected *Set
547+
}{
548+
{
549+
set: NewSet(MakePathOrDie("a", "b", "c")),
550+
expected: NewSet(
551+
MakePathOrDie("a", "b", "c"),
552+
MakePathOrDie("a", "b"),
553+
MakePathOrDie("a"),
554+
),
555+
},
556+
{
557+
set: NewSet(MakePathOrDie("a", "b", "c"), MakePathOrDie("a", "d"), MakePathOrDie("a", "c", "e")),
558+
expected: NewSet(
559+
MakePathOrDie("a", "b", "c"),
560+
MakePathOrDie("a", "b"),
561+
MakePathOrDie("a", "c", "e"),
562+
MakePathOrDie("a", "c"),
563+
MakePathOrDie("a", "d"),
564+
MakePathOrDie("a"),
565+
),
566+
},
567+
}
568+
569+
for _, test := range table {
570+
t.Run(fmt.Sprintf("%v", test.set), func(t *testing.T) {
571+
got := test.set.NestedSet()
572+
if !got.Equals(test.expected) {
573+
t.Errorf("expected %v, got %v (missing: %v/superfluous: %v)",
574+
test.expected,
575+
got,
576+
test.expected.Difference(got),
577+
got.Difference(test.expected),
578+
)
579+
}
580+
})
581+
}
582+
}
583+
544584
func TestSetNodeMapIterate(t *testing.T) {
545585
set := &SetNodeMap{}
546586
toAdd := 5

0 commit comments

Comments
 (0)