Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor package internal/attribute to not use generics. #3725

Merged
merged 15 commits into from
Feb 15, 2023
16 changes: 8 additions & 8 deletions attribute/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func BoolValue(v bool) Value {

// BoolSliceValue creates a BOOLSLICE Value.
func BoolSliceValue(v []bool) Value {
return Value{vtype: BOOLSLICE, slice: attribute.SliceValue(v)}
return Value{vtype: BOOLSLICE, slice: attribute.BoolSliceValue(v)}
}

// IntValue creates an INT64 Value.
Expand Down Expand Up @@ -99,7 +99,7 @@ func Int64Value(v int64) Value {

// Int64SliceValue creates an INT64SLICE Value.
func Int64SliceValue(v []int64) Value {
return Value{vtype: INT64SLICE, slice: attribute.SliceValue(v)}
return Value{vtype: INT64SLICE, slice: attribute.Int64SliceValue(v)}
}

// Float64Value creates a FLOAT64 Value.
Expand All @@ -112,7 +112,7 @@ func Float64Value(v float64) Value {

// Float64SliceValue creates a FLOAT64SLICE Value.
func Float64SliceValue(v []float64) Value {
return Value{vtype: FLOAT64SLICE, slice: attribute.SliceValue(v)}
return Value{vtype: FLOAT64SLICE, slice: attribute.Float64SliceValue(v)}
}

// StringValue creates a STRING Value.
Expand All @@ -125,7 +125,7 @@ func StringValue(v string) Value {

// StringSliceValue creates a STRINGSLICE Value.
func StringSliceValue(v []string) Value {
return Value{vtype: STRINGSLICE, slice: attribute.SliceValue(v)}
return Value{vtype: STRINGSLICE, slice: attribute.StringSliceValue(v)}
}

// Type returns a type of the Value.
Expand All @@ -149,7 +149,7 @@ func (v Value) AsBoolSlice() []bool {
}

func (v Value) asBoolSlice() []bool {
return attribute.AsSlice[bool](v.slice)
return attribute.AsBoolSlice(v.slice)
}

// AsInt64 returns the int64 value. Make sure that the Value's type is
Expand All @@ -168,7 +168,7 @@ func (v Value) AsInt64Slice() []int64 {
}

func (v Value) asInt64Slice() []int64 {
return attribute.AsSlice[int64](v.slice)
return attribute.AsInt64Slice(v.slice)
}

// AsFloat64 returns the float64 value. Make sure that the Value's
Expand All @@ -187,7 +187,7 @@ func (v Value) AsFloat64Slice() []float64 {
}

func (v Value) asFloat64Slice() []float64 {
return attribute.AsSlice[float64](v.slice)
return attribute.AsFloat64Slice(v.slice)
}

// AsString returns the string value. Make sure that the Value's type
Expand All @@ -206,7 +206,7 @@ func (v Value) AsStringSlice() []string {
}

func (v Value) asStringSlice() []string {
return attribute.AsSlice[string](v.slice)
return attribute.AsStringSlice(v.slice)
}

type unknownValueType struct{}
Expand Down
82 changes: 74 additions & 8 deletions internal/attribute/attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,90 @@ import (
"reflect"
)

// SliceValue convert a slice into an array with same elements as slice.
func SliceValue[T bool | int64 | float64 | string](v []T) any {
var zero T
// SliceValue convert a bool slice into an array with same elements as slice.
Petrie marked this conversation as resolved.
Show resolved Hide resolved
func BoolSliceValue(v []bool) any {
var zero bool
cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))
copy(cp.Elem().Slice(0, len(v)).Interface().([]T), v)
copy(cp.Elem().Slice(0, len(v)).Interface().([]bool), v)
return cp.Elem().Interface()
}

// AsSlice convert an array into a slice into with same elements as array.
func AsSlice[T bool | int64 | float64 | string](v any) []T {
// SliceValue convert a int64 slice into an array with same elements as slice.
Petrie marked this conversation as resolved.
Show resolved Hide resolved
func Int64SliceValue(v []int64) any {
var zero int64
cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))
copy(cp.Elem().Slice(0, len(v)).Interface().([]int64), v)
return cp.Elem().Interface()
}

// SliceValue convert a float64 slice into an array with same elements as slice.
Petrie marked this conversation as resolved.
Show resolved Hide resolved
func Float64SliceValue(v []float64) any {
var zero float64
cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))
copy(cp.Elem().Slice(0, len(v)).Interface().([]float64), v)
return cp.Elem().Interface()
}

// SliceValue convert a string slice into an array with same elements as slice.
Petrie marked this conversation as resolved.
Show resolved Hide resolved
func StringSliceValue(v []string) any {
var zero string
cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))
copy(cp.Elem().Slice(0, len(v)).Interface().([]string), v)
return cp.Elem().Interface()
}

// AsSlice convert an bool array into a slice into with same elements as array.
Petrie marked this conversation as resolved.
Show resolved Hide resolved
func AsBoolSlice(v any) []bool {
rv := reflect.ValueOf(v)
if rv.Type().Kind() != reflect.Array {
return nil
}
var zero bool
correctLen := rv.Len()
correctType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero))
cpy := reflect.New(correctType)
_ = reflect.Copy(cpy.Elem(), rv)
return cpy.Elem().Slice(0, correctLen).Interface().([]bool)
}

// AsSlice convert an int64 array into a slice into with same elements as array.
Petrie marked this conversation as resolved.
Show resolved Hide resolved
func AsInt64Slice(v any) []int64 {
rv := reflect.ValueOf(v)
if rv.Type().Kind() != reflect.Array {
return nil
}
var zero int64
correctLen := rv.Len()
correctType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero))
cpy := reflect.New(correctType)
_ = reflect.Copy(cpy.Elem(), rv)
return cpy.Elem().Slice(0, correctLen).Interface().([]int64)
}

// AsSlice convert an float64 array into a slice into with same elements as array.
Petrie marked this conversation as resolved.
Show resolved Hide resolved
func AsFloat64Slice(v any) []float64 {
rv := reflect.ValueOf(v)
if rv.Type().Kind() != reflect.Array {
return nil
}
var zero float64
correctLen := rv.Len()
correctType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero))
cpy := reflect.New(correctType)
_ = reflect.Copy(cpy.Elem(), rv)
return cpy.Elem().Slice(0, correctLen).Interface().([]float64)
}

// AsSlice convert an string array into a slice into with same elements as array.
Petrie marked this conversation as resolved.
Show resolved Hide resolved
func AsStringSlice(v any) []string {
rv := reflect.ValueOf(v)
if rv.Type().Kind() != reflect.Array {
return nil
}
var zero T
var zero string
correctLen := rv.Len()
correctType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero))
cpy := reflect.New(correctType)
_ = reflect.Copy(cpy.Elem(), rv)
return cpy.Elem().Slice(0, correctLen).Interface().([]T)
return cpy.Elem().Slice(0, correctLen).Interface().([]string)
}
180 changes: 180 additions & 0 deletions internal/attribute/attribute_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package attribute

import (
"reflect"
"testing"
)

func TestBoolSliceValue(t *testing.T) {
dmathieu marked this conversation as resolved.
Show resolved Hide resolved
type args struct {
v []bool
}
tests := []struct {
name string
args args
want interface{}
}{
{name: "TestBoolSliceValue", args: args{v: []bool{true, false, true}}, want: [3]bool{true, false, true}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := BoolSliceValue(tt.args.v); !reflect.DeepEqual(got, tt.want) {
t.Errorf("BoolSliceValue() = %v, want %v", got, tt.want)
}
})
}
}

func TestInt64SliceValue(t *testing.T) {
type args struct {
v []int64
}
tests := []struct {
name string
args args
want any
}{
{name: "TestInt64SliceValue", args: args{[]int64{1, 2}}, want: [2]int64{1, 2}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Int64SliceValue(tt.args.v); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Int64SliceValue() = %v, want %v", got, tt.want)
}
})
}
}

func TestFloat64SliceValue(t *testing.T) {
type args struct {
v []float64
}
tests := []struct {
name string
args args
want any
}{
{name: "TestFloat64SliceValue", args: args{v: []float64{1, 2.3}}, want: [2]float64{1, 2.3}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Float64SliceValue(tt.args.v); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Float64SliceValue() = %v, want %v", got, tt.want)
}
})
}
}

func TestStringSliceValue(t *testing.T) {
type args struct {
v []string
}
tests := []struct {
name string
args args
want any
}{
{name: "TestStringSliceValue", args: args{[]string{"123456", "2"}}, want: [2]string{"123456", "2"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := StringSliceValue(tt.args.v); !reflect.DeepEqual(got, tt.want) {
t.Errorf("StringSliceValue() = %v, want %v", got, tt.want)
}
})
}
}

func TestAsBoolSlice(t *testing.T) {
type args struct {
v any
}
tests := []struct {
name string
args args
want []bool
}{
{name: "TestAsBoolSlice", args: args{[2]bool{true, false}}, want: []bool{true, false}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := AsBoolSlice(tt.args.v); !reflect.DeepEqual(got, tt.want) {
t.Errorf("AsSliceBool() = %v, want %v", got, tt.want)
}
})
}
}

func TestAsInt64Slice(t *testing.T) {
type args struct {
v any
}
tests := []struct {
name string
args args
want []int64
}{
{name: "TestAsInt64Slice", args: args{[2]int64{1, 3}}, want: []int64{1, 3}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := AsInt64Slice(tt.args.v); !reflect.DeepEqual(got, tt.want) {
t.Errorf("AsInt64Slice() = %v, want %v", got, tt.want)
}
})
}
}

func TestAsFloat64Slice(t *testing.T) {
type args struct {
v any
}
tests := []struct {
name string
args args
want []float64
}{
{name: "TestAsFloat64Slice", args: args{[2]float64{1.2, 3.1}}, want: []float64{1.2, 3.1}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := AsFloat64Slice(tt.args.v); !reflect.DeepEqual(got, tt.want) {
t.Errorf("AsFloat64Slice() = %v, want %v", got, tt.want)
}
})
}
}

func TestAsStringSlice(t *testing.T) {
type args struct {
v any
}
tests := []struct {
name string
args args
want []string
}{
{name: "TestAsStringSlice", args: args{[2]string{"1234", "12"}}, want: []string{"1234", "12"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := AsStringSlice(tt.args.v); !reflect.DeepEqual(got, tt.want) {
t.Errorf("AsStringSlice() = %v, want %v", got, tt.want)
}
})
}
}