Skip to content

Commit

Permalink
add ColumnsIntE/ColumnsInt64E/ColumnsFloat64E/ColumnsStringE
Browse files Browse the repository at this point in the history
  • Loading branch information
shockerli committed Mar 22, 2021
1 parent 5eba7d5 commit 7b9b831
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 0 deletions.
68 changes: 68 additions & 0 deletions cvte.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,74 @@ func ColumnsE(val interface{}, field interface{}) (sl []interface{}, err error)
return nil, fmt.Errorf("unsupported type: %s", rt.Kind())
}

func ColumnsIntE(val interface{}, field interface{}) (sl []int, err error) {
list, err := ColumnsE(val, field)
if err != nil {
return
}

for _, v := range list {
vv, err := IntE(v)
if err != nil {
return nil, err
}
sl = append(sl, vv)
}

return
}

func ColumnsInt64E(val interface{}, field interface{}) (sl []int64, err error) {
list, err := ColumnsE(val, field)
if err != nil {
return
}

for _, v := range list {
vv, err := Int64E(v)
if err != nil {
return nil, err
}
sl = append(sl, vv)
}

return
}

func ColumnsFloat64E(val interface{}, field interface{}) (sl []float64, err error) {
list, err := ColumnsE(val, field)
if err != nil {
return
}

for _, v := range list {
vv, err := Float64E(v)
if err != nil {
return nil, err
}
sl = append(sl, vv)
}

return
}

func ColumnsStringE(val interface{}, field interface{}) (sl []string, err error) {
list, err := ColumnsE(val, field)
if err != nil {
return
}

for _, v := range list {
vv, err := StringE(v)
if err != nil {
return nil, err
}
sl = append(sl, vv)
}

return
}

// returns the value with base type
func indirect(a interface{}) (val interface{}, rt reflect.Type, rv reflect.Value) {
if a == nil {
Expand Down
153 changes: 153 additions & 0 deletions cvte_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1565,3 +1565,156 @@ func TestTimeE(t *testing.T) {
assert.Equal(t, tt.expect, v.UTC(), msg)
}
}

func TestColumnsIntE(t *testing.T) {
tests := []struct {
input interface{}
field interface{}
expect []int
isErr bool
}{
{[]interface{}{TestStructE{D1: 1, DD: &TestStructD{D1: 2}}}, "D1", []int{1}, false},

{[]TestStructE{{D1: 1}, {D1: 2}}, "D1", []int{1, 2}, false},
{[]map[string]interface{}{{"1": 111, "DDD": "123"}, {"2": 222, "DDD": "321"}}, "DDD", []int{123, 321}, false},
{[]map[string]interface{}{{"1": 111, "DDD": "123"}, {"2": 222, "DDD": "321"}, {"DDD": nil}}, "DDD", []int{123, 321, 0}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": 123}, 2: {"2": 222, "DDD": "321"}, 3: {"DDD": nil}}, "DDD", []int{123, 321, 0}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": 123}, 2: {"2": 222, "DDD": "321"}}, "DDD", []int{123, 321}, false},
{map[int]TestStructD{1: {11}, 2: {22}}, "D1", []int{11, 22}, false},

// errors
{"Name", "xxx", nil, true},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": func() {}}}, "DDD", nil, true},
}

for i, tt := range tests {
msg := fmt.Sprintf(
"i = %d, input[%+v], field[%+v], expect[%+v], isErr[%v]",
i, tt.input, tt.field, tt.expect, tt.isErr,
)

v, err := cvt.ColumnsIntE(tt.input, tt.field)
if tt.isErr {
assert.Error(t, err, msg)
continue
}

assert.NoError(t, err, msg)
assert.Equal(t, tt.expect, v, msg)
}
}

func TestColumnsInt64E(t *testing.T) {
tests := []struct {
input interface{}
field interface{}
expect []int64
isErr bool
}{
{[]interface{}{TestStructE{D1: 1, DD: &TestStructD{D1: 2}}}, "D1", []int64{1}, false},

{[]TestStructE{{D1: 1}, {D1: 2}}, "D1", []int64{1, 2}, false},
{[]map[string]interface{}{{"1": 111, "DDD": "123"}, {"2": 222, "DDD": "321"}}, "DDD", []int64{123, 321}, false},
{[]map[string]interface{}{{"1": 111, "DDD": "123"}, {"2": 222, "DDD": "321"}, {"DDD": nil}}, "DDD", []int64{123, 321, 0}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": 123}, 2: {"2": 222, "DDD": "321"}, 3: {"DDD": nil}}, "DDD", []int64{123, 321, 0}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": 123}, 2: {"2": 222, "DDD": "321"}}, "DDD", []int64{123, 321}, false},
{map[int]TestStructD{1: {11}, 2: {22}}, "D1", []int64{11, 22}, false},

// errors
{"Name", "xxx", nil, true},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": func() {}}}, "DDD", nil, true},
}

for i, tt := range tests {
msg := fmt.Sprintf(
"i = %d, input[%+v], field[%+v], expect[%+v], isErr[%v]",
i, tt.input, tt.field, tt.expect, tt.isErr,
)

v, err := cvt.ColumnsInt64E(tt.input, tt.field)
if tt.isErr {
assert.Error(t, err, msg)
continue
}

assert.NoError(t, err, msg)
assert.Equal(t, tt.expect, v, msg)
}
}

func TestColumnsStringE(t *testing.T) {
tests := []struct {
input interface{}
field interface{}
expect []string
isErr bool
}{
{[]interface{}{TestStructE{D1: 1, DD: &TestStructD{D1: 2}}}, "D1", []string{"1"}, false},

{[]TestStructE{{D1: 1}, {D1: 2}}, "D1", []string{"1", "2"}, false},
{[]map[string]interface{}{{"1": 111, "DDD": "123"}, {"2": 222, "DDD": "321"}}, "DDD", []string{"123", "321"}, false},
{[]map[string]interface{}{{"1": 111, "DDD": "123"}, {"2": 222, "DDD": "321"}, {"DDD": nil}}, "DDD", []string{"123", "321", ""}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": 123}, 2: {"2": 222, "DDD": "321"}, 3: {"DDD": nil}}, "DDD", []string{"123", "321", ""}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": 12.3}, 2: {"2": 222, "DDD": 32.1}}, "DDD", []string{"12.3", "32.1"}, false},
{map[int]TestStructD{1: {11}, 2: {22}}, "D1", []string{"11", "22"}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": TestStructC{C1: "XXX"}}}, "DDD", []string{"XXX"}, false},

// errors
{"Name", "xxx", nil, true},
{[]map[string]interface{}{{"2": 222, "DDD": func() {}}}, "DDD", nil, true},
}

for i, tt := range tests {
msg := fmt.Sprintf(
"i = %d, input[%+v], field[%+v], expect[%+v], isErr[%v]",
i, tt.input, tt.field, tt.expect, tt.isErr,
)

v, err := cvt.ColumnsStringE(tt.input, tt.field)
if tt.isErr {
assert.Error(t, err, msg)
continue
}

assert.NoError(t, err, msg)
assert.Equal(t, tt.expect, v, msg)
}
}

func TestColumnsFloat64E(t *testing.T) {
tests := []struct {
input interface{}
field interface{}
expect []float64
isErr bool
}{
{[]interface{}{TestStructE{D1: 1, DD: &TestStructD{D1: 2}}}, "D1", []float64{1}, false},
{[]TestStructE{{D1: 1}, {D1: 2}}, "D1", []float64{1, 2}, false},
{[]map[string]interface{}{{"1": 111, "DDD": "123"}, {"2": 222, "DDD": "32.1"}}, "DDD", []float64{123, 32.1}, false},
{[]map[string]interface{}{{"1": 111, "DDD": "123"}, {"2": 222, "DDD": "32.1"}, {"DDD": nil}}, "DDD", []float64{123, 32.1, 0}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": 12.3}, 2: {"2": 222, "DDD": "321"}, 3: {"DDD": nil}}, "DDD", []float64{12.3, 321, 0}, false},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": 12.3}, 2: {"2": 222, "DDD": 32.1}}, "DDD", []float64{12.3, 32.1}, false},
{map[int]TestStructD{1: {11}, 2: {22}}, "D1", []float64{11, 22}, false},

// errors
{"Name", "xxx", nil, true},
{map[int]map[string]interface{}{1: {"1": 111, "DDD": TestStructC{C1: "XXX"}}}, "DDD", nil, true},
{[]map[string]interface{}{{"2": 222, "DDD": func() {}}}, "DDD", nil, true},
}

for i, tt := range tests {
msg := fmt.Sprintf(
"i = %d, input[%+v], field[%+v], expect[%+v], isErr[%v]",
i, tt.input, tt.field, tt.expect, tt.isErr,
)

v, err := cvt.ColumnsFloat64E(tt.input, tt.field)
if tt.isErr {
assert.Error(t, err, msg)
continue
}

assert.NoError(t, err, msg)
assert.Equal(t, tt.expect, v, msg)
}
}

0 comments on commit 7b9b831

Please sign in to comment.