types/views: add Slice.All iterator

And convert a few callers as an example, but nowhere near all.

Updates #12912

Change-Id: I5eaa12a29a6cd03b58d6f1072bd27bc0467852f2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2024-07-24 10:55:36 -07:00
committed by Brad Fitzpatrick
parent aedfb82876
commit e54c81d1d0
3 changed files with 35 additions and 13 deletions

View File

@@ -10,6 +10,7 @@ import (
"encoding/json"
"errors"
"fmt"
"iter"
"maps"
"reflect"
"slices"
@@ -208,6 +209,17 @@ type Slice[T any] struct {
ж []T
}
// All returns an iterator over v.
func (v Slice[T]) All() iter.Seq2[int, T] {
return func(yield func(int, T) bool) {
for i, v := range v.ж {
if !yield(i, v) {
return
}
}
}
}
// MapKey returns a unique key for a slice, based on its address and length.
func (v Slice[T]) MapKey() SliceMapKey[T] { return mapKey(v.ж) }

View File

@@ -6,8 +6,10 @@ package views
import (
"bytes"
"encoding/json"
"fmt"
"net/netip"
"reflect"
"slices"
"strings"
"testing"
"unsafe"
@@ -412,3 +414,15 @@ func TestContainsPointers(t *testing.T) {
})
}
}
func TestSliceRange(t *testing.T) {
sv := SliceOf([]string{"foo", "bar"})
var got []string
for i, v := range sv.All() {
got = append(got, fmt.Sprintf("%d-%s", i, v))
}
want := []string{"0-foo", "1-bar"}
if !slices.Equal(got, want) {
t.Errorf("got %q; want %q", got, want)
}
}