Ver código fonte

parseval fix

0x4a52466c696e74 3 meses atrás
pai
commit
788b920541
3 arquivos alterados com 33 adições e 1 exclusões
  1. 15 0
      serialize.go
  2. 8 0
      tools.go
  3. 10 1
      z_test.go

+ 15 - 0
serialize.go

@@ -2,6 +2,7 @@ package rest
 
 import (
 	"fmt"
+	"log"
 	"reflect"
 	"strings"
 
@@ -35,6 +36,7 @@ func parseVal(from, to reflect.Value, fieldName string) IErrorArgs {
 func parseType(from, to reflect.Value, fieldName string) IErrorArgs {
 	from = realValue(from)
 	to = realValue(to)
+	log.Println("=== to", to.Kind(), to.Type().Name())
 	switch to.Kind() {
 	case reflect.Interface:
 		if from.Kind() != reflect.Invalid {
@@ -97,6 +99,7 @@ func parseStruct(from, to reflect.Value, fieldName string) IErrorArgs {
 			return f.RestFrom(from.Interface())
 		}
 	}
+loop:
 	for i := 0; i < to.NumField(); i++ {
 		required := false
 		// устанавливаем тип и указатель поля объекта, куда копируем
@@ -104,6 +107,18 @@ func parseStruct(from, to reflect.Value, fieldName string) IErrorArgs {
 		fVal := to.Field(i)
 		// проверяем тег, если он есть
 		tag := fType.Tag.Get("rest")
+		if fType.Type.Kind() == reflect.Ptr {
+			elem := fType.Type.Elem()
+			if elem.Kind() == reflect.Struct {
+				if fVal.IsNil() {
+					fVal.Set(reflect.New(elem))
+					if ierr := parseStruct(from, fVal.Elem(), prefixFieldName(fieldName, fType.Name)); ierr != nil {
+						return ierr
+					}
+					continue loop
+				}
+			}
+		}
 		if len(tag) > 0 {
 			required = strings.Contains(tag, "required")
 		}

+ 8 - 0
tools.go

@@ -1,12 +1,20 @@
 package rest
 
 import (
+	"fmt"
 	"io"
 	"reflect"
 
 	"git.ali33.ru/fcg-xvii/go-tools/json"
 )
 
+func prefixFieldName(prefix, fieldName string) string {
+	if len(prefix) > 0 {
+		return fmt.Sprintf("%s.%s", prefix, fieldName)
+	}
+	return fieldName
+}
+
 // конверторы
 
 // Int64ToBytes упаковывает int64 в срез байтов заданной длины

+ 10 - 1
z_test.go

@@ -232,19 +232,28 @@ func TestFielderList(t *testing.T) {
 	m.LogPretty()
 }
 
+type RRequest struct {
+	Count int
+	Okko  string `rest:"required"`
+}
+
 type Tickers struct {
+	*RRequest
 	TickerIDS []string
 }
 
-func TestSerialize(t *testing.T) {
+func TestSerializeRaw(t *testing.T) {
 	m := json.Map{
 		"ticker_ids": []string{"1", "2", "3"},
+		"count":      10,
+		"okko":       "ok-val",
 	}
 	var ti Tickers
 	if err := Serialize(m, &ti); err != nil {
 		t.Fatal(err)
 	}
 	log.Println(ti.TickerIDS)
+	log.Println(ti.RRequest)
 }
 
 func TestServer(t *testing.T) {