aboutsummaryrefslogtreecommitdiff
path: root/src/log/slog/value.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/log/slog/value.go')
-rw-r--r--src/log/slog/value.go34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/log/slog/value.go b/src/log/slog/value.go
index 71a59d2639..224848f695 100644
--- a/src/log/slog/value.go
+++ b/src/log/slog/value.go
@@ -164,9 +164,32 @@ func DurationValue(v time.Duration) Value {
// GroupValue returns a new Value for a list of Attrs.
// The caller must not subsequently mutate the argument slice.
func GroupValue(as ...Attr) Value {
+ // Remove empty groups.
+ // It is simpler overall to do this at construction than
+ // to check each Group recursively for emptiness.
+ if n := countEmptyGroups(as); n > 0 {
+ as2 := make([]Attr, 0, len(as)-n)
+ for _, a := range as {
+ if !a.Value.isEmptyGroup() {
+ as2 = append(as2, a)
+ }
+ }
+ as = as2
+ }
return Value{num: uint64(len(as)), any: groupptr(unsafe.SliceData(as))}
}
+// countEmptyGroups returns the number of empty group values in its argument.
+func countEmptyGroups(as []Attr) int {
+ n := 0
+ for _, a := range as {
+ if a.Value.isEmptyGroup() {
+ n++
+ }
+ }
+ return n
+}
+
// AnyValue returns a Value for the supplied value.
//
// If the supplied value is of type Value, it is returned
@@ -399,6 +422,17 @@ func (v Value) Equal(w Value) bool {
}
}
+// isEmptyGroup reports whether v is a group that has no attributes.
+func (v Value) isEmptyGroup() bool {
+ if v.Kind() != KindGroup {
+ return false
+ }
+ // We do not need to recursively examine the group's Attrs for emptiness,
+ // because GroupValue removed them when the group was constructed, and
+ // groups are immutable.
+ return len(v.group()) == 0
+}
+
// append appends a text representation of v to dst.
// v is formatted as with fmt.Sprint.
func (v Value) append(dst []byte) []byte {