Skip to content

Commit

Permalink
value does not panic and change List to Slice
Browse files Browse the repository at this point in the history
  • Loading branch information
pellared committed Feb 20, 2024
1 parent e89444d commit 147762f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 54 deletions.
6 changes: 3 additions & 3 deletions log/kind_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

96 changes: 54 additions & 42 deletions log/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ package log // import "go.opentelemetry.io/otel/log"

import (
"bytes"
"errors"
"fmt"
"math"
"strconv"
"unsafe"

"go.opentelemetry.io/otel/internal/global"
)

// A Value can represent a structured value.
Expand All @@ -25,14 +28,14 @@ type Value struct {
// the length for String, Bytes, List, Map.
num uint64
// If any is of type Kind, then the value is in num as described above.
// Otherwise (if is of type stringptr, listptr, sliceptr or mapptr) it contains the value.
// Otherwise (if is of type stringptr, bytesptr, sliceptr or mapptr) it contains the value.
any any
}

type (
stringptr *byte // used in Value.any when the Value is a string
bytesptr *byte // used in Value.any when the Value is a []byte
listptr *Value // used in Value.any when the Value is a []Value
sliceptr *Value // used in Value.any when the Value is a []Value
mapptr *KeyValue // used in Value.any when the Value is a []KeyValue
)

Expand All @@ -47,7 +50,7 @@ const (
KindInt64
KindString
KindBytes
KindList
KindSlice
KindMap
)

Expand All @@ -62,15 +65,17 @@ func (v Value) Kind() Kind {
return KindString
case bytesptr:
return KindBytes
case listptr:
return KindList
case sliceptr:
return KindSlice
case mapptr:
return KindMap
default:
return KindEmpty
}
}

var errBadKind = errors.New("bad kind")

// StringValue returns a new [Value] for a string.
func StringValue(value string) Value {
return Value{num: uint64(len(value)), any: stringptr(unsafe.StringData(value))}
Expand Down Expand Up @@ -106,24 +111,25 @@ func BytesValue(v []byte) Value {
return Value{num: uint64(len(v)), any: bytesptr(unsafe.SliceData(v))}
}

// ListValue returns a [Value] for a list of [Value].
// SliceValue returns a [Value] for a slice of [Value].
// The caller must not subsequently mutate the argument slice.
func ListValue(vs ...Value) Value {
return Value{num: uint64(len(vs)), any: listptr(unsafe.SliceData(vs))}
func SliceValue(vs ...Value) Value {
return Value{num: uint64(len(vs)), any: sliceptr(unsafe.SliceData(vs))}
}

// MapValue returns a new [Value] for a list of key-value pairs.
// MapValue returns a new [Value] for a slice of key-value pairs.
// The caller must not subsequently mutate the argument slice.
func MapValue(kvs ...KeyValue) Value {
return Value{num: uint64(len(kvs)), any: mapptr(unsafe.SliceData(kvs))}
}

// AsAny returns v's value as an any.
// It returns nil and logs error if v's kind is invalid.
func (v Value) AsAny() any {
switch v.Kind() {
case KindMap:
return v.mapValue()
case KindList:
case KindSlice:
return v.list()
case KindInt64:
return int64(v.num)
Expand All @@ -138,37 +144,41 @@ func (v Value) AsAny() any {
case KindEmpty:
return nil
default:
panic(fmt.Sprintf("bad kind: %s", v.Kind()))
global.Error(errBadKind, "AsAny", "kind", v.Kind())
return nil
}
}

// AsString returns Value's value as a string, formatted like [fmt.Sprint]. It panics
// if v is not a string.
// AsString returns Value's value as a string.
// It returns empty string and logs error if v is not a string.
func (v Value) AsString() string {
if sp, ok := v.any.(stringptr); ok {
return unsafe.String(sp, v.num)
}
panic("AsString: bad kind")
global.Error(errBadKind, "AsString", "kind", v.Kind())
return ""
}

func (v Value) str() string {
return unsafe.String(v.any.(stringptr), v.num)
}

// AsInt64 returns v's value as an int64. It panics
// if v is not a signed integer.
// AsInt64 returns v's value as an int64.
// It returns 0 and logs error if v is not a signed integer.
func (v Value) AsInt64() int64 {
if g, w := v.Kind(), KindInt64; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
global.Error(errBadKind, "AsInt64", "kind", v.Kind())
return 0
}
return int64(v.num)
}

// AsBool returns v's value as a bool. It panics
// if v is not a bool.
// AsBool returns v's value as a bool.
// It returns false and logs error if v is not a bool.
func (v Value) AsBool() bool {
if g, w := v.Kind(), KindBool; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
global.Error(errBadKind, "AsBool", "kind", v.Kind())
return false
}
return v.bool()
}
Expand All @@ -177,11 +187,12 @@ func (v Value) bool() bool {
return v.num == 1
}

// AsFloat64 returns v's value as a float64. It panics
// if v is not a float64.
// AsFloat64 returns v's value as a float64.
// It returns false and logs error if v is not a float64.
func (v Value) AsFloat64() float64 {
if g, w := v.Kind(), KindFloat64; g != w {
panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
global.Error(errBadKind, "AsFloat64", "kind", v.Kind())
return 0
}

return v.float()
Expand All @@ -192,38 +203,41 @@ func (v Value) float() float64 {
}

// AsBytes returns v's value as a []byte.
// It panics if v's [Kind] is not [KindBytes].
// It returns nil and logs error if v's [Kind] is not [KindBytes].
func (v Value) AsBytes() []byte {
if sp, ok := v.any.(bytesptr); ok {
return unsafe.Slice((*byte)(sp), v.num)
}
panic("AsBytes: bad kind")
global.Error(errBadKind, "AsBytes", "kind", v.Kind())
return nil
}

func (v Value) bytes() []byte {
return unsafe.Slice((*byte)(v.any.(bytesptr)), v.num)
}

// AsList returns v's value as a []Value.
// It panics if v's [Kind] is not [KindList].
func (v Value) AsList() []Value {
if sp, ok := v.any.(listptr); ok {
// AsSlice returns v's value as a []Value.
// It returns nil and logs error if v's [Kind] is not [KindSlice].
func (v Value) AsSlice() []Value {
if sp, ok := v.any.(sliceptr); ok {
return unsafe.Slice((*Value)(sp), v.num)
}
panic("AsList: bad kind")
global.Error(errBadKind, "AsSlice", "kind", v.Kind())
return nil
}

func (v Value) list() []Value {
return unsafe.Slice((*Value)(v.any.(listptr)), v.num)
return unsafe.Slice((*Value)(v.any.(sliceptr)), v.num)
}

// AsMap returns v's value as a []KeyValue.
// It panics if v's [Kind] is not [KindMap].
// It returns nil and logs error if v's [Kind] is not [KindMap].
func (v Value) AsMap() []KeyValue {
if sp, ok := v.any.(mapptr); ok {
return unsafe.Slice((*KeyValue)(sp), v.num)
}
panic("AsMap: bad kind")
global.Error(errBadKind, "AsMap", "kind", v.Kind())
return nil
}

func (v Value) mapValue() []KeyValue {
Expand All @@ -249,7 +263,7 @@ func (v Value) Equal(w Value) bool {
return v.str() == w.str()
case KindFloat64:
return v.float() == w.float()
case KindList:
case KindSlice:
return sliceEqualFunc(v.list(), w.list(), Value.Equal)
case KindMap:
return sliceEqualFunc(v.mapValue(), w.mapValue(), KeyValue.Equal)
Expand All @@ -262,9 +276,7 @@ func (v Value) Equal(w Value) bool {
}
}

// String returns Value's value as a string, formatted like [fmt.Sprint]. Unlike
// the methods Int64, Float64, and so on, which panic if v is of the
// wrong kind, String never panics.
// String returns Value's value as a string, formatted like [fmt.Sprint].
func (v Value) String() string {
switch v.Kind() {
case KindString:
Expand All @@ -279,12 +291,12 @@ func (v Value) String() string {
return fmt.Sprint(v.bytes())
case KindMap:
return fmt.Sprint(v.mapValue())
case KindList:
case KindSlice:
return fmt.Sprint(v.list())
case KindEmpty:
return emptyString
default:
panic(fmt.Sprintf("bad kind: %s", v.Kind()))
return "<invalid>"
}
}

Expand Down Expand Up @@ -328,9 +340,9 @@ func Bytes(key string, v []byte) KeyValue {
return KeyValue{key, BytesValue(v)}
}

// Bytes returns an KeyValue for a list of [Value].
func List(key string, args ...Value) KeyValue {
return KeyValue{key, ListValue(args...)}
// Slice returns an KeyValue for a slice of [Value].
func Slice(key string, args ...Value) KeyValue {
return KeyValue{key, SliceValue(args...)}
}

// Map returns an KeyValue for a Map [Value].
Expand Down
18 changes: 9 additions & 9 deletions log/value_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestKind(t *testing.T) {
{KindEmpty, "Empty", 0},
{KindFloat64, "Float64", 2},
{KindInt64, "Int64", 3},
{KindList, "List", 6},
{KindSlice, "Slice", 6},
{KindMap, "Map", 7},
{KindString, "String", 4},
}
Expand All @@ -49,9 +49,9 @@ func TestValueEqual(t *testing.T) {
BoolValue(false),
StringValue("hi"),
BytesValue([]byte{1, 3, 5}),
ListValue(IntValue(3), StringValue("foo")),
SliceValue(IntValue(3), StringValue("foo")),
MapValue(Bool("b", true), Int("i", 3)),
MapValue(List("l", IntValue(3), StringValue("foo")), Bytes("b", []byte{3, 5, 7})),
MapValue(Slice("l", IntValue(3), StringValue("foo")), Bytes("b", []byte{3, 5, 7})),
}
for i, v1 := range vals {
for j, v2 := range vals {
Expand All @@ -74,7 +74,7 @@ func TestValueString(t *testing.T) {
{BoolValue(true), "true"},
{StringValue("foo"), "foo"},
{BytesValue([]byte{2, 4, 6}), "[2 4 6]"},
{ListValue(IntValue(3), StringValue("foo")), "[3 foo]"},
{SliceValue(IntValue(3), StringValue("foo")), "[3 foo]"},
{MapValue(Int("a", 1), Bool("b", true)), "[a=1 b=true]"},
{Value{}, "<nil>"},
} {
Expand Down Expand Up @@ -144,7 +144,7 @@ func TestValueAny(t *testing.T) {
{int64(11), Int64Value(11)},
{1.5, Float64Value(1.5)},
{[]byte{1, 2, 3}, BytesValue([]byte{1, 2, 3})},
{[]Value{IntValue(3)}, ListValue(IntValue(3))},
{[]Value{IntValue(3)}, SliceValue(IntValue(3))},
{[]KeyValue{Int("i", 3)}, MapValue(Int("i", 3))},
{nil, Value{}},
} {
Expand All @@ -160,8 +160,8 @@ func TestEmptyMap(t *testing.T) {
}

func TestEmptyList(t *testing.T) {
l := ListValue()
got := l.AsList()
l := SliceValue()
got := l.AsSlice()
assert.Nil(t, got)
}

Expand All @@ -178,8 +178,8 @@ func TestMapValueWithEmptyMaps(t *testing.T) {

func TestListValueWithEmptyValues(t *testing.T) {
// Preserve empty values.
l := ListValue(Value{})
got := l.AsList()
l := SliceValue(Value{})
got := l.AsSlice()
want := []Value{{}}
assert.Equal(t, want, got)
}
Expand Down

0 comments on commit 147762f

Please sign in to comment.