1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-01-03 22:52:30 +02:00

[key] add Stringer and Infer methods (#662)

* add Stringer and Infer methods

* fix nit

* Update api/key/key.go

Co-Authored-By: Tyler Yahn <MrAlias@users.noreply.github.com>

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
Liz Fong-Jones 2020-04-24 19:40:49 -04:00 committed by GitHub
parent 1de7f68bfc
commit 33e60677db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 122 additions and 0 deletions

View File

@ -15,6 +15,8 @@
package key
import (
"fmt"
"go.opentelemetry.io/otel/api/core"
)
@ -71,6 +73,12 @@ func String(k, v string) core.KeyValue {
return New(k).String(v)
}
// Stringer creates a new key-value pair with a passed name and a string
// value generated by the passed Stringer interface.
func Stringer(k string, v fmt.Stringer) core.KeyValue {
return New(k).String(v.String())
}
// Int creates a new key-value pair instance with a passed name and
// either an int32 or an int64 value, depending on whether the int
// type is 32 or 64 bits wide.
@ -84,3 +92,34 @@ func Int(k string, v int) core.KeyValue {
func Uint(k string, v uint) core.KeyValue {
return New(k).Uint(v)
}
// Infer creates a new key-value pair instance with a passed name and
// automatic type inference. This is slower, and not type-safe.
func Infer(k string, value interface{}) core.KeyValue {
switch v := value.(type) {
case bool:
return Bool(k, v)
case int:
return Int(k, v)
case uint:
return Uint(k, v)
case int32:
return Int32(k, v)
case int64:
return Int64(k, v)
case uint32:
return Uint32(k, v)
case uint64:
return Uint64(k, v)
case float32:
return Float32(k, v)
case float64:
return Float64(k, v)
case string:
return String(k, v)
case fmt.Stringer:
return Stringer(k, v)
default:
return String(k, fmt.Sprint(v))
}
}

View File

@ -15,6 +15,7 @@
package key_test
import (
"strings"
"testing"
"github.com/google/go-cmp/cmp"
@ -119,3 +120,85 @@ func TestKeyValueConstructors(t *testing.T) {
})
}
}
func TestInfer(t *testing.T) {
builder := &strings.Builder{}
builder.WriteString("foo")
for _, testcase := range []struct {
key string
value interface{}
wantType core.ValueType
wantValue interface{}
}{
{
key: "bool type inferred",
value: true,
wantType: core.BOOL,
wantValue: true,
},
{
key: "int64 type inferred",
value: int64(42),
wantType: core.INT64,
wantValue: int64(42),
},
{
key: "uint64 type inferred",
value: uint64(42),
wantType: core.UINT64,
wantValue: uint64(42),
},
{
key: "float64 type inferred",
value: float64(42.1),
wantType: core.FLOAT64,
wantValue: 42.1,
},
{
key: "int32 type inferred",
value: int32(42),
wantType: core.INT32,
wantValue: int32(42),
},
{
key: "uint32 type inferred",
value: uint32(42),
wantType: core.UINT32,
wantValue: uint32(42),
},
{
key: "float32 type inferred",
value: float32(42.1),
wantType: core.FLOAT32,
wantValue: float32(42.1),
},
{
key: "string type inferred",
value: "foo",
wantType: core.STRING,
wantValue: "foo",
},
{
key: "stringer type inferred",
value: builder,
wantType: core.STRING,
wantValue: "foo",
},
{
key: "unknown value serialized as %v",
value: nil,
wantType: core.STRING,
wantValue: "<nil>",
},
} {
t.Logf("Running test case %s", testcase.key)
kv := key.Infer(testcase.key, testcase.value)
if kv.Value.Type() != testcase.wantType {
t.Errorf("wrong value type, got %#v, expected %#v", kv.Value.Type(), testcase.wantType)
}
got := kv.Value.AsInterface()
if diff := cmp.Diff(testcase.wantValue, got); diff != "" {
t.Errorf("+got, -want: %s", diff)
}
}
}