mirror of
https://gitee.com/johng/gf.git
synced 2024-11-30 03:07:45 +08:00
improve package gconv/cli
This commit is contained in:
parent
aa6705f493
commit
d9c1e1f576
@ -512,11 +512,12 @@ func generateDaoInternal(
|
||||
}
|
||||
|
||||
func replaceDefaultVar(in cGenDaoInternalInput, origin string) string {
|
||||
if !in.WithTime {
|
||||
return origin
|
||||
var tplDatetimeStr string
|
||||
if in.WithTime {
|
||||
tplDatetimeStr = fmt.Sprintf(`Created at %s`, createdAt.String())
|
||||
}
|
||||
return gstr.ReplaceByMap(origin, g.MapStrStr{
|
||||
tplVarDatetimeStr: createdAt.String(),
|
||||
tplVarDatetimeStr: tplDatetimeStr,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -453,51 +453,84 @@ func bindVarToReflectValue(structFieldValue reflect.Value, value interface{}, ma
|
||||
// Note that the slice element might be type of struct,
|
||||
// so it uses Struct function doing the converting internally.
|
||||
case reflect.Slice, reflect.Array:
|
||||
a := reflect.Value{}
|
||||
v := reflect.ValueOf(value)
|
||||
if v.Kind() == reflect.Slice || v.Kind() == reflect.Array {
|
||||
a = reflect.MakeSlice(structFieldValue.Type(), v.Len(), v.Len())
|
||||
if v.Len() > 0 {
|
||||
t := a.Index(0).Type()
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
e := reflect.New(t.Elem()).Elem()
|
||||
if err = doStruct(v.Index(i).Interface(), e, nil, ""); err != nil {
|
||||
// Note there's reflect conversion mechanism here.
|
||||
e.Set(reflect.ValueOf(v.Index(i).Interface()).Convert(t))
|
||||
}
|
||||
a.Index(i).Set(e.Addr())
|
||||
} else {
|
||||
e := reflect.New(t).Elem()
|
||||
if err = doStruct(v.Index(i).Interface(), e, nil, ""); err != nil {
|
||||
// Note there's reflect conversion mechanism here.
|
||||
e.Set(reflect.ValueOf(v.Index(i).Interface()).Convert(t))
|
||||
}
|
||||
a.Index(i).Set(e)
|
||||
var (
|
||||
reflectArray reflect.Value
|
||||
reflectValue = reflect.ValueOf(value)
|
||||
)
|
||||
if reflectValue.Kind() == reflect.Slice || reflectValue.Kind() == reflect.Array {
|
||||
reflectArray = reflect.MakeSlice(structFieldValue.Type(), reflectValue.Len(), reflectValue.Len())
|
||||
if reflectValue.Len() > 0 {
|
||||
var (
|
||||
elemType = reflectArray.Index(0).Type()
|
||||
elemTypeName string
|
||||
converted bool
|
||||
)
|
||||
for i := 0; i < reflectValue.Len(); i++ {
|
||||
converted = false
|
||||
elemTypeName = elemType.Name()
|
||||
if elemTypeName == "" {
|
||||
elemTypeName = elemType.String()
|
||||
}
|
||||
var elem reflect.Value
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
elem = reflect.New(elemType.Elem()).Elem()
|
||||
} else {
|
||||
elem = reflect.New(elemType).Elem()
|
||||
}
|
||||
if elem.Kind() == reflect.Struct {
|
||||
if err = doStruct(reflectValue.Index(i).Interface(), elem, nil, ""); err == nil {
|
||||
converted = true
|
||||
}
|
||||
}
|
||||
if !converted {
|
||||
elem.Set(reflect.ValueOf(doConvert(doConvertInput{
|
||||
FromValue: reflectValue.Index(i).Interface(),
|
||||
ToTypeName: elemTypeName,
|
||||
ReferValue: elem,
|
||||
})))
|
||||
}
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
// Before it sets the `elem` to array, do pointer converting if necessary.
|
||||
elem = elem.Addr()
|
||||
}
|
||||
reflectArray.Index(i).Set(elem)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
a = reflect.MakeSlice(structFieldValue.Type(), 1, 1)
|
||||
t := a.Index(0).Type()
|
||||
if t.Kind() == reflect.Ptr {
|
||||
// Pointer element.
|
||||
e := reflect.New(t.Elem()).Elem()
|
||||
if err = doStruct(value, e, nil, ""); err != nil {
|
||||
// Note there's reflect conversion mechanism here.
|
||||
e.Set(reflect.ValueOf(value).Convert(t))
|
||||
}
|
||||
a.Index(0).Set(e.Addr())
|
||||
} else {
|
||||
// Just consider it as struct element. (Although it might be other types but not basic types, eg: map)
|
||||
e := reflect.New(t).Elem()
|
||||
if err = doStruct(value, e, nil, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
a.Index(0).Set(e)
|
||||
reflectArray = reflect.MakeSlice(structFieldValue.Type(), 1, 1)
|
||||
var (
|
||||
elem reflect.Value
|
||||
elemType = reflectArray.Index(0).Type()
|
||||
elemTypeName = elemType.Name()
|
||||
converted bool
|
||||
)
|
||||
if elemTypeName == "" {
|
||||
elemTypeName = elemType.String()
|
||||
}
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
elem = reflect.New(elemType.Elem()).Elem()
|
||||
} else {
|
||||
elem = reflect.New(elemType).Elem()
|
||||
}
|
||||
if elem.Kind() == reflect.Struct {
|
||||
if err = doStruct(value, elem, nil, ""); err == nil {
|
||||
converted = true
|
||||
}
|
||||
}
|
||||
if !converted {
|
||||
elem.Set(reflect.ValueOf(doConvert(doConvertInput{
|
||||
FromValue: value,
|
||||
ToTypeName: elemTypeName,
|
||||
ReferValue: elem,
|
||||
})))
|
||||
}
|
||||
if elemType.Kind() == reflect.Ptr {
|
||||
// Before it sets the `elem` to array, do pointer converting if necessary.
|
||||
elem = elem.Addr()
|
||||
}
|
||||
reflectArray.Index(0).Set(elem)
|
||||
}
|
||||
structFieldValue.Set(a)
|
||||
structFieldValue.Set(reflectArray)
|
||||
|
||||
case reflect.Ptr:
|
||||
item := reflect.New(structFieldValue.Type().Elem())
|
||||
|
@ -356,7 +356,7 @@ func Test_Struct_Attr_CustomType2(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
user := new(User)
|
||||
err := gconv.Struct(g.Map{"id": g.Slice{1, 2}, "name": "john"}, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Id, g.Slice{1, 2})
|
||||
t.Assert(user.Name, "john")
|
||||
})
|
||||
@ -1301,3 +1301,22 @@ func Test_Struct_Issue1597(t *testing.T) {
|
||||
t.Assert(s.B, `{"c":3}`)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Scan_WithDoubleSliceAttribute(t *testing.T) {
|
||||
inputData := [][]string{
|
||||
{"aa", "bb", "cc"},
|
||||
{"11", "22", "33"},
|
||||
}
|
||||
data := struct {
|
||||
Data [][]string
|
||||
}{
|
||||
Data: inputData,
|
||||
}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
jv := gjson.New(gjson.MustEncodeString(data))
|
||||
err := jv.Scan(&data)
|
||||
t.AssertNil(err)
|
||||
t.Assert(data.Data, inputData)
|
||||
})
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user