types/views: add SliceView.All iterator (#13536)

And convert a all relevant usages.

Updates #12912

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
Joe Tsai
2024-09-20 13:55:33 -07:00
committed by GitHub
parent 3e9ca6c64b
commit dc86d3589c
4 changed files with 50 additions and 10 deletions

View File

@@ -147,6 +147,17 @@ type SliceView[T ViewCloner[T, V], V StructView[T]] struct {
ж []T
}
// All returns an iterator over v.
func (v SliceView[T, V]) All() iter.Seq2[int, V] {
return func(yield func(int, V) bool) {
for i := range v.ж {
if !yield(i, v.ж[i].View()) {
return
}
}
}
}
// MarshalJSON implements json.Marshaler.
func (v SliceView[T, V]) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) }

View File

@@ -426,3 +426,35 @@ func TestSliceRange(t *testing.T) {
t.Errorf("got %q; want %q", got, want)
}
}
type testStruct struct{ value string }
func (p *testStruct) Clone() *testStruct {
if p == nil {
return p
}
return &testStruct{p.value}
}
func (p *testStruct) View() testStructView { return testStructView{p} }
type testStructView struct{ p *testStruct }
func (v testStructView) Valid() bool { return v.p != nil }
func (v testStructView) AsStruct() *testStruct {
if v.p == nil {
return nil
}
return v.p.Clone()
}
func TestSliceViewRange(t *testing.T) {
vs := SliceOfViews([]*testStruct{{value: "foo"}, {value: "bar"}})
var got []string
for i, v := range vs.All() {
got = append(got, fmt.Sprintf("%d-%s", i, v.AsStruct().value))
}
want := []string{"0-foo", "1-bar"}
if !slices.Equal(got, want) {
t.Errorf("got %q; want %q", got, want)
}
}