Skip to content

Commit

Permalink
Support IntMapE
Browse files Browse the repository at this point in the history
  • Loading branch information
shockerli committed Oct 15, 2023
1 parent a414b3b commit eefd106
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 10 deletions.
13 changes: 9 additions & 4 deletions doc/content/en/type/time.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ weight: 50

{{< toc >}}

## Time

## Function
- Time
- TimeE
## TimeE

## Examples
```go
cvt.Time("2009-11-10 23:00:00 +0000 UTC")
cvt.Time("2018-10-21T23:21:29+0200")
Expand All @@ -24,5 +22,12 @@ cvt.Time(1482597504)
cvt.Time(time.Date(2009, 2, 13, 23, 31, 30, 0, time.Local))
```

## TimeInLocation
cvt.TimeInLocation("2009-02-13 23:31:30", time.FixedZone("UTC", 8*3600))

## TimeInLocationE
cvt.TimeInLocationE("2009-02-13 23:31:30", time.FixedZone("UTC", 8*3600))


> More case see unit: `time_test.go`
13 changes: 9 additions & 4 deletions doc/content/zh-cn/type/time.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ weight: 50

{{< toc >}}

## Time

## 方法
- Time
- TimeE
## TimeE

## 示例
```go
cvt.Time("2009-11-10 23:00:00 +0000 UTC")
cvt.Time("2018-10-21T23:21:29+0200")
Expand All @@ -34,5 +32,12 @@ cvt.Time(json.Number("1234567890"))
cvt.Time(json.Number("2016-03-06 15:28:01"))
```

## TimeInLocation
cvt.TimeInLocation("2009-02-13 23:31:30", time.FixedZone("UTC", 8*3600))

## TimeInLocationE
cvt.TimeInLocationE("2009-02-13 23:31:30", time.FixedZone("UTC", 8*3600))


> 更多示例请看单元测试:`time_test.go`
46 changes: 45 additions & 1 deletion map.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,48 @@ import (
"reflect"
)

// IntMapE convert an interface to `map[int]interface{}`
// * Support JSON string of map
// * Support any `map` type
func IntMapE(val interface{}) (m map[int]interface{}, err error) {
m = make(map[int]interface{})
if val == nil {
return nil, errUnsupportedTypeNil
}

// direct type(for improve performance)
switch v := val.(type) {
case map[int]interface{}:
return v, nil
}

// indirect type
_, rv := Indirect(val)
switch rv.Kind() {
case reflect.Map:
var idx int
for _, key := range rv.MapKeys() {
idx, err = IntE(key.Interface())
if err != nil {
return
}
m[idx] = rv.MapIndex(key).Interface()
}
case reflect.Slice:
// []byte
// Example: []byte(`{1:"bob",2:18}`)
if rv.Type().Elem().Kind() == reflect.Uint8 {
err = json.Unmarshal(rv.Bytes(), &m)
}
case reflect.String:
// JSON string of map
// Example: `{1:"bob",2:18}`
err = json.Unmarshal([]byte(rv.String()), &m)
}

return
}

// StringMapE convert an interface to `map[string]interface{}`
// * Support JSON string of map
// * Support any `map` type
Expand Down Expand Up @@ -37,12 +79,14 @@ func StringMapE(val interface{}) (m map[string]interface{}, err error) {
case reflect.Struct:
m = struct2map(rv)
case reflect.Slice:
// []byte
// []byte, JSON
// Example: []byte(`{"name":"bob","age":18}`)
if rv.Type().Elem().Kind() == reflect.Uint8 {
err = json.Unmarshal(rv.Bytes(), &m)
}
case reflect.String:
// JSON string of map
// Example: `{"name":"bob","age":18}`
err = json.Unmarshal([]byte(rv.String()), &m)
}

Expand Down
47 changes: 46 additions & 1 deletion map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package cvt_test

import (
"fmt"
"github.com/shockerli/cvt"
"testing"

"github.com/shockerli/cvt"
)

func TestStringMapE(t *testing.T) {
Expand Down Expand Up @@ -89,3 +90,47 @@ func TestStringMapE(t *testing.T) {
assertEqual(t, tt.expect, v, "[WithE] "+msg)
}
}

func TestIntMapE(t *testing.T) {
tests := []struct {
input interface{}
expect map[int]interface{}
isErr bool
}{
// JSON
{`{"1":"cvt","2":3.21}`, map[int]interface{}{1: "cvt", 2: 3.21}, false},
{`{"1":"cvt","2":"convert"}`, map[int]interface{}{1: "cvt", 2: "convert"}, false},
{`{"1":"cvt","2":true}`, map[int]interface{}{1: "cvt", 2: true}, false},
{[]byte(`{"1":"cvt","2":true}`), map[int]interface{}{1: "cvt", 2: true}, false},
{AliasTypeString(`{"1":"cvt","2":true}`), map[int]interface{}{1: "cvt", 2: true}, false},
{AliasTypeBytes(`{"1":"cvt","2":true}`), map[int]interface{}{1: "cvt", 2: true}, false},

// Map
{map[int]interface{}{}, map[int]interface{}{}, false},
{map[int]interface{}{1: "cvt", 2: 3.21}, map[int]interface{}{1: "cvt", 2: 3.21}, false},
{map[interface{}]interface{}{1: "cvt", 2: 3.21}, map[int]interface{}{1: "cvt", 2: 3.21}, false},
{map[interface{}]interface{}{"1": "cvt", "2": 3.21}, map[int]interface{}{1: "cvt", 2: 3.21}, false},

// errors
{nil, nil, true},
{map[interface{}]interface{}{"name": "cvt", 3.21: 3.21}, map[int]interface{}{1: "cvt", 2: 3.21}, true},
{"", nil, true},
{"hello", nil, true},
}

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

v, err := cvt.IntMapE(tt.input)
if tt.isErr {
assertError(t, err, "[HasErr] "+msg)
continue
}

assertNoError(t, err, "[NoErr] "+msg)
assertEqual(t, tt.expect, v, "[WithE] "+msg)
}
}
7 changes: 7 additions & 0 deletions time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,20 @@ func TestTimeInLocation_BaseLine(t *testing.T) {
}

func TestTimeInLocationE(t *testing.T) {
var (
locUTC8 = time.FixedZone("UTC", 8*3600)
)

tests := []struct {
input interface{}
loc *time.Location
expect time.Time
isErr bool
}{
{nil, nil, time.Time{}, false},
{"2009-11-10 23:00:00 +0800", nil, time.Date(2009, 11, 10, 23, 0, 0, 0, locUTC8), false}, // Time.String()
{"2009-02-13 23:31:30", locUTC8, time.Date(2009, 2, 13, 23, 31, 30, 0, locUTC8), false},
{"2009-02-13 23:31:30", locUTC8, time.Date(2009, 2, 13, 23, 31, 30, 0, locUTC8), false},

// errors
{"2006", nil, time.Time{}, true},
Expand Down

1 comment on commit eefd106

@vercel
Copy link

@vercel vercel bot commented on eefd106 Oct 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.