Skip to content

Commit

Permalink
🐛 fix: get value from struct
Browse files Browse the repository at this point in the history
  • Loading branch information
0xE8551CCB committed Oct 8, 2019
1 parent 47100e0 commit ba576a5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
17 changes: 16 additions & 1 deletion field.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,22 @@ func (f *schemaField) setValue(v interface{}) error {
}

func (f *schemaField) realInputValue(v interface{}) (interface{}, error) {
switch r := v.(type) {
var iv interface{}
rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.Ptr:
iv = v
case reflect.Struct:
// input is `SomeStruct`
// but `*SomeStruct` implements `Valuer` interface.
tmpValue := reflect.New(rv.Type())
tmpValue.Elem().Set(rv)
iv = tmpValue.Interface()
default:
return v, nil
}

switch r := iv.(type) {
case driver.Valuer:
return r.Value()
case Valuer:
Expand Down
39 changes: 34 additions & 5 deletions field_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package portal

import (
"fmt"
"testing"
"time"

Expand Down Expand Up @@ -182,13 +183,26 @@ func (p *Person) Value() (interface{}, error) {
return p.Name, nil
}

type Timestamp int
type Timestamp struct {
tm time.Time
}

func (t *Timestamp) SetValue(v interface{}) error {
*t = Timestamp(v.(time.Time).Unix())
switch timeValue := v.(type) {
case time.Time:
t.tm = timeValue
case *time.Time:
t.tm = *timeValue
default:
return fmt.Errorf("expect type `time.Time`, not `%T`", v)
}
return nil
}

func (t *Timestamp) Value() (interface{}, error) {
return t.tm, nil
}

func TestField_SetValue(t *testing.T) {
type BarSchema struct {
ID string
Expand All @@ -207,14 +221,29 @@ func TestField_SetValue(t *testing.T) {
assert.Equal(t, "foo", f.Value().(string))

f = newField(schema, schema.innerStruct().Field("Ts"))

now := time.Now()
assert.Nil(t, f.setValue(now))
assert.Equal(t, Timestamp(now.Unix()), *f.Value().(*Timestamp))
assert.Equal(t, Timestamp{now}, *f.Value().(*Timestamp))

f = newField(schema, schema.innerStruct().Field("Ts"))
assert.Nil(t, f.setValue(&Timestamp{now}))
assert.Equal(t, Timestamp{now}, *f.Value().(*Timestamp))

f = newField(schema, schema.innerStruct().Field("Ts"))
assert.Nil(t, f.setValue(Timestamp{now}))
assert.Equal(t, Timestamp{now}, *f.Value().(*Timestamp))

f = newField(schema, schema.innerStruct().Field("Ts2"))
assert.Nil(t, f.setValue(Timestamp{now}))
assert.Equal(t, Timestamp{now}, f.Value().(Timestamp))

f = newField(schema, schema.innerStruct().Field("Ts2"))
assert.Nil(t, f.setValue(&Timestamp{now}))
assert.Equal(t, Timestamp{now}, f.Value().(Timestamp))

f = newField(schema, schema.innerStruct().Field("Ts2"))
assert.Nil(t, f.setValue(now))
assert.Equal(t, Timestamp(now.Unix()), f.Value().(Timestamp))
assert.Equal(t, Timestamp{now}, f.Value().(Timestamp))
}

// BenchmarkNewField-4 3622506 317 ns/op
Expand Down

0 comments on commit ba576a5

Please sign in to comment.