Record.Attrs stops as soon as its argument function returns false.
Fixes #59060.
Change-Id: I578d64635e0e52b0fcdbc57f6d5a27a6efac8c70
Reviewed-on: https://go-review.googlesource.com/c/go/+/484096
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
--- /dev/null
+pkg log/slog, method (Record) Attrs(func(Attr) bool) #59060
+
defer s.prefix.Free()
s.prefix.WriteString(s.h.groupPrefix)
s.openGroups()
defer s.prefix.Free()
s.prefix.WriteString(s.h.groupPrefix)
s.openGroups()
+ r.Attrs(func(a Attr) bool {
})
if s.h.json {
// Close all open groups.
})
if s.h.json {
// Close all open groups.
buf.WriteByte(' ')
buf.WriteString("msg=")
buf.WriteString(r.Message)
buf.WriteByte(' ')
buf.WriteString("msg=")
buf.WriteString(r.Message)
- r.Attrs(func(a slog.Attr) {
+ r.Attrs(func(a slog.Attr) bool {
buf.WriteByte(' ')
buf.WriteString(a.Key)
buf.WriteByte('=')
h.appendValue(buf, a.Value)
buf.WriteByte(' ')
buf.WriteString(a.Key)
buf.WriteByte('=')
h.appendValue(buf, a.Value)
})
buf.WriteByte('\n')
_, err := h.w.Write(*buf)
})
buf.WriteByte('\n')
_, err := h.w.Write(*buf)
func attrSlice(r slog.Record) []slog.Attr {
var as []slog.Attr
func attrSlice(r slog.Record) []slog.Attr {
var as []slog.Attr
- r.Attrs(func(a slog.Attr) { as = append(as, a) })
+ r.Attrs(func(a slog.Attr) bool { as = append(as, a); return true })
}
// Attrs calls f on each Attr in the Record.
}
// Attrs calls f on each Attr in the Record.
+// Iteration stops if f returns false.
// The Attrs are already resolved.
// The Attrs are already resolved.
-func (r Record) Attrs(f func(Attr)) {
+func (r Record) Attrs(f func(Attr) bool) {
for i := 0; i < r.nFront; i++ {
for i := 0; i < r.nFront; i++ {
+ if !f(r.front[i]) {
+ return
+ }
}
for _, a := range r.back {
}
for _, a := range r.back {
+ if !f(a) {
+ return
+ }
if got := attrsSlice(r); !attrsEqual(got, as) {
t.Errorf("got %v, want %v", got, as)
}
if got := attrsSlice(r); !attrsEqual(got, as) {
t.Errorf("got %v, want %v", got, as)
}
+
+ // Early return.
+ var got []Attr
+ r.Attrs(func(a Attr) bool {
+ got = append(got, a)
+ return len(got) < 2
+ })
+ want := as[:2]
+ if !attrsEqual(got, want) {
+ t.Errorf("got %v, want %v", got, want)
+ }
}
func TestRecordSourceLine(t *testing.T) {
}
func TestRecordSourceLine(t *testing.T) {
func attrsSlice(r Record) []Attr {
s := make([]Attr, 0, r.NumAttrs())
func attrsSlice(r Record) []Attr {
s := make([]Attr, 0, r.NumAttrs())
- r.Attrs(func(a Attr) { s = append(s, a) })
+ r.Attrs(func(a Attr) bool { s = append(s, a); return true })
for j := 0; j < nAttrs; j++ {
r.AddAttrs(Int("k", j))
}
for j := 0; j < nAttrs; j++ {
r.AddAttrs(Int("k", j))
}
- r.Attrs(func(b Attr) { a = b })
+ r.Attrs(func(b Attr) bool { a = b; return true })