Chromium Code Reviews| Index: service/datastore/pls_impl.go |
| diff --git a/service/datastore/pls_impl.go b/service/datastore/pls_impl.go |
| index f6656d3ad92bfe021d460f83a18c7ac7e6e76695..6e2f2b651ec749616584736db01a8d46078831e7 100644 |
| --- a/service/datastore/pls_impl.go |
| +++ b/service/datastore/pls_impl.go |
| @@ -12,10 +12,8 @@ import ( |
| "strconv" |
| "strings" |
| "sync" |
| - "time" |
| "unicode" |
| - "github.com/luci/gae/service/blobstore" |
| "github.com/luci/luci-go/common/errors" |
| ) |
| @@ -138,8 +136,6 @@ func loadInner(codec *structCodec, structValue reflect.Value, index int, name st |
| return "multiple-valued property requires a slice field type" |
| } |
| - pVal := p.Value() |
| - |
| if ret, ok := doConversion(v); ok { |
| if ret != "" { |
| return ret |
| @@ -149,79 +145,61 @@ func loadInner(codec *structCodec, structValue reflect.Value, index int, name st |
| if v.Type().Implements(typeOfKey) { |
| knd = reflect.Interface |
| } |
| + |
| + project := PTNull |
| + overflow := (func(interface{}) bool)(nil) |
| + set := (func(interface{}))(nil) |
|
iannucci
2015/09/10 03:56:58
Now that we have the Project method, this code got
|
| + |
| switch knd { |
| case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
| - x, ok := pVal.(int64) |
| - if !ok && pVal != nil { |
| - return typeMismatchReason(pVal, v) |
| - } |
| - if v.OverflowInt(x) { |
| - return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type()) |
| - } |
| - v.SetInt(x) |
| + project = PTInt |
| + overflow = func(x interface{}) bool { return v.OverflowInt(x.(int64)) } |
| + set = func(x interface{}) { v.SetInt(x.(int64)) } |
| case reflect.Bool: |
| - x, ok := pVal.(bool) |
| - if !ok && pVal != nil { |
| - return typeMismatchReason(pVal, v) |
| - } |
| - v.SetBool(x) |
| + project = PTBool |
| + set = func(x interface{}) { v.SetBool(x.(bool)) } |
| case reflect.String: |
| - switch x := pVal.(type) { |
| - case blobstore.Key: |
| - v.SetString(string(x)) |
| - case string: |
| - v.SetString(x) |
| - default: |
| - if pVal != nil { |
| - return typeMismatchReason(pVal, v) |
| - } |
| - } |
| + project = PTString |
| + set = func(x interface{}) { v.SetString(x.(string)) } |
| case reflect.Float32, reflect.Float64: |
| - x, ok := pVal.(float64) |
| - if !ok && pVal != nil { |
| - return typeMismatchReason(pVal, v) |
| - } |
| - if v.OverflowFloat(x) { |
| - return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type()) |
| - } |
| - v.SetFloat(x) |
| + project = PTFloat |
| + overflow = func(x interface{}) bool { return v.OverflowFloat(x.(float64)) } |
| + set = func(x interface{}) { v.SetFloat(x.(float64)) } |
| case reflect.Interface: |
| - x, ok := pVal.(Key) |
| - if !ok && pVal != nil { |
| - return typeMismatchReason(pVal, v) |
| - } |
| - if x != nil { |
| - v.Set(reflect.ValueOf(x)) |
| + project = PTKey |
| + set = func(x interface{}) { |
| + if k, ok := x.(Key); ok { |
| + v.Set(reflect.ValueOf(k)) |
| + } |
| } |
| case reflect.Struct: |
| switch v.Type() { |
| case typeOfTime: |
| - x, ok := pVal.(time.Time) |
| - if !ok && pVal != nil { |
| - return typeMismatchReason(pVal, v) |
| - } |
| - v.Set(reflect.ValueOf(x)) |
| + project = PTTime |
| + set = func(x interface{}) { v.Set(reflect.ValueOf(x)) } |
| case typeOfGeoPoint: |
| - x, ok := pVal.(GeoPoint) |
| - if !ok && pVal != nil { |
| - return typeMismatchReason(pVal, v) |
| - } |
| - v.Set(reflect.ValueOf(x)) |
| + project = PTGeoPoint |
| + set = func(x interface{}) { v.Set(reflect.ValueOf(x)) } |
| default: |
| - panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(pVal, v))) |
| + panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(p.value, v))) |
| } |
| case reflect.Slice: |
| - switch x := pVal.(type) { |
| - case []byte: |
| - v.SetBytes(x) |
| - case ByteString: |
| - v.SetBytes([]byte(x)) |
| - default: |
| - panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(pVal, v))) |
| + project = PTBytes |
| + set = func(x interface{}) { |
| + v.SetBytes(reflect.ValueOf(x).Bytes()) |
| } |
| default: |
| - panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(pVal, v))) |
| + panic(fmt.Errorf("helper: impossible: %s", typeMismatchReason(p.value, v))) |
| + } |
| + |
| + pVal, err := p.Project(project) |
| + if err != nil { |
| + return typeMismatchReason(p.value, v) |
| + } |
| + if overflow != nil && overflow(pVal) { |
| + return fmt.Sprintf("value %v overflows struct field of type %v", pVal, v.Type()) |
| } |
| + set(pVal) |
| } |
| if slice.IsValid() { |
| slice.Set(reflect.Append(slice, v)) |