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) |
+ |
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)) |