Skip to content

Commit 0ab28c9

Browse files
committed
attributes: format non-Stringer, non-string types as %T=%v
Avoid formatting errors (%!p(...)) on value types and pointers when formatting attributes, while preserving full type and value information.
1 parent 6d697e4 commit 0ab28c9

2 files changed

Lines changed: 18 additions & 10 deletions

File tree

attributes/attributes.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,16 @@ func (a *Attributes) String() string {
137137
}
138138

139139
func str(x any) (s string) {
140+
if x == nil {
141+
return "<nil>"
142+
}
140143
if v, ok := x.(fmt.Stringer); ok {
141144
return fmt.Sprint(v)
142-
} else if v, ok := x.(string); ok {
145+
}
146+
if v, ok := x.(string); ok {
143147
return v
144148
}
145-
return fmt.Sprintf("<%p>", x)
149+
return fmt.Sprintf("%T=%v", x, x)
146150
}
147151

148152
// MarshalJSON helps implement the json.Marshaler interface, thereby rendering

attributes/attributes_test.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ func ExampleAttributes_WithValue() {
6767

6868
func ExampleAttributes_String() {
6969
type key struct{}
70+
type namedKey string
7071
var typedNil *stringerVal
7172
a1 := attributes.New(key{}, typedNil) // typed nil implements [fmt.Stringer]
7273
a2 := attributes.New(key{}, (*stringerVal)(nil)) // typed nil implements [fmt.Stringer]
@@ -76,6 +77,7 @@ func ExampleAttributes_String() {
7677
a6 := attributes.New(key{}, stringerVal{s: "two"})
7778
a7 := attributes.New(key{}, stringVal{s: "two"})
7879
a8 := attributes.New(1, true)
80+
a9 := attributes.New(namedKey("my.custom.key"), "val")
7981
fmt.Println("a1:", a1.String())
8082
fmt.Println("a2:", a2.String())
8183
fmt.Println("a3:", a3.String())
@@ -84,15 +86,17 @@ func ExampleAttributes_String() {
8486
fmt.Println("a6:", a6.String())
8587
fmt.Println("a7:", a7.String())
8688
fmt.Println("a8:", a8.String())
89+
fmt.Println("a9:", a9.String())
8790
// Output:
88-
// a1: {"<%!p(attributes_test.key={})>": "<nil>" }
89-
// a2: {"<%!p(attributes_test.key={})>": "<nil>" }
90-
// a3: {"<%!p(attributes_test.key={})>": "<0x0>" }
91-
// a4: {"<%!p(attributes_test.key={})>": "<%!p(<nil>)>" }
92-
// a5: {"<%!p(attributes_test.key={})>": "<%!p(int=1)>" }
93-
// a6: {"<%!p(attributes_test.key={})>": "two" }
94-
// a7: {"<%!p(attributes_test.key={})>": "<%!p(attributes_test.stringVal={two})>" }
95-
// a8: {"<%!p(int=1)>": "<%!p(bool=true)>" }
91+
// a1: {"attributes_test.key={}": "<nil>" }
92+
// a2: {"attributes_test.key={}": "<nil>" }
93+
// a3: {"attributes_test.key={}": "*attributes_test.stringVal=<nil>" }
94+
// a4: {"attributes_test.key={}": "<nil>" }
95+
// a5: {"attributes_test.key={}": "int=1" }
96+
// a6: {"attributes_test.key={}": "two" }
97+
// a7: {"attributes_test.key={}": "attributes_test.stringVal={two}" }
98+
// a8: {"int=1": "bool=true" }
99+
// a9: {"attributes_test.namedKey=my.custom.key": "val" }
96100
}
97101

98102
// Test that two attributes with different content are not Equal.

0 commit comments

Comments
 (0)