mirror of
https://github.com/danog/liquid.git
synced 2024-11-27 05:44:40 +01:00
Convert returns an error; create MustConvert
This commit is contained in:
parent
e2fd3bbf81
commit
4df3f04aae
@ -33,7 +33,7 @@ func convertArguments(fn reflect.Value, in []interface{}) []reflect.Value {
|
|||||||
if arg == nil {
|
if arg == nil {
|
||||||
out[i] = reflect.Zero(rt.In(i))
|
out[i] = reflect.Zero(rt.In(i))
|
||||||
} else {
|
} else {
|
||||||
out[i] = Convert(arg, rt.In(i))
|
out[i] = reflect.ValueOf(MustConvert(arg, rt.In(i)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,51 +8,49 @@ import (
|
|||||||
|
|
||||||
var timeType = reflect.TypeOf(time.Now())
|
var timeType = reflect.TypeOf(time.Now())
|
||||||
|
|
||||||
|
// MustConvert converts a value to the type.
|
||||||
|
func MustConvert(value interface{}, t reflect.Type) interface{} {
|
||||||
|
out, err := Convert(value, t)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// Convert value to the type. This is a more aggressive conversion, that will
|
// Convert value to the type. This is a more aggressive conversion, that will
|
||||||
// recursively create new map and slice values as necessary. It doesn't
|
// recursively create new map and slice values as necessary. It doesn't
|
||||||
// handle circular references.
|
// handle circular references.
|
||||||
//
|
func Convert(value interface{}, t reflect.Type) (interface{}, error) {
|
||||||
// TODO It's weird that this takes an interface{} but returns a Value
|
|
||||||
func Convert(value interface{}, t reflect.Type) reflect.Value {
|
|
||||||
r := reflect.ValueOf(value)
|
r := reflect.ValueOf(value)
|
||||||
if r.Type().ConvertibleTo(t) {
|
if r.Type().ConvertibleTo(t) {
|
||||||
return r.Convert(t)
|
return r.Convert(t).Interface(), nil
|
||||||
}
|
}
|
||||||
if reflect.PtrTo(r.Type()) == t {
|
if reflect.PtrTo(r.Type()) == t {
|
||||||
return reflect.ValueOf(&value)
|
return &value, nil
|
||||||
}
|
}
|
||||||
if r.Kind() == reflect.String && t == timeType {
|
if r.Kind() == reflect.String && t == timeType {
|
||||||
v, err := ParseTime(value.(string))
|
return ParseTime(value.(string))
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(v)
|
|
||||||
}
|
}
|
||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
n, err := strconv.Atoi(value.(string))
|
return strconv.Atoi(value.(string))
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(n)
|
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
n, err := strconv.ParseFloat(value.(string), 64)
|
return strconv.ParseFloat(value.(string), 64)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return reflect.ValueOf(n)
|
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
if r.Kind() != reflect.Array && r.Kind() != reflect.Slice {
|
if r.Kind() != reflect.Array && r.Kind() != reflect.Slice {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
x := reflect.MakeSlice(t, 0, r.Len())
|
out := reflect.MakeSlice(t, 0, r.Len())
|
||||||
for i := 0; i < r.Len(); i++ {
|
for i := 0; i < r.Len(); i++ {
|
||||||
c := Convert(r.Index(i).Interface(), t.Elem())
|
item, err := Convert(r.Index(i).Interface(), t.Elem())
|
||||||
x = reflect.Append(x, c)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out = reflect.Append(out, reflect.ValueOf(item))
|
||||||
}
|
}
|
||||||
return x
|
return out.Interface(), nil
|
||||||
}
|
}
|
||||||
panic(genericErrorf("generic.Convert can't convert %#v<%s> to %v", value, r.Type(), t))
|
return nil, genericErrorf("generic.Convert can't convert %#v<%s> to %v", value, r.Type(), t)
|
||||||
}
|
}
|
||||||
|
|
||||||
var dateLayouts = []string{
|
var dateLayouts = []string{
|
||||||
|
@ -65,7 +65,8 @@ func TestConvert(t *testing.T) {
|
|||||||
for i, test := range convertTests {
|
for i, test := range convertTests {
|
||||||
t.Run(fmt.Sprintf("%02d", i+1), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%02d", i+1), func(t *testing.T) {
|
||||||
typ := reflect.TypeOf(test.proto)
|
typ := reflect.TypeOf(test.proto)
|
||||||
value := Convert(test.value, typ).Interface()
|
value, err := Convert(test.value, typ)
|
||||||
|
require.NoError(t, err)
|
||||||
require.Equalf(t, test.expected, value, "Convert %#v -> %#v", test.value, test, typ)
|
require.Equalf(t, test.expected, value, "Convert %#v -> %#v", test.value, test, typ)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user