Maksimov V Vladimir пре 1 недеља
родитељ
комит
7200be749a
1 измењених фајлова са 97 додато и 0 уклоњено
  1. 97 0
      json/jm.go

+ 97 - 0
json/jm.go

@@ -0,0 +1,97 @@
+package json
+
+import (
+	"fmt"
+	"log"
+	"reflect"
+)
+
+// Заполняет поля структуры из map по тегам `jm`
+func FillStructFromMap(ptr any, data map[string]any) error {
+	v := reflect.ValueOf(ptr)
+	if v.Kind() != reflect.Ptr || v.IsNil() {
+		return fmt.Errorf("expected pointer to struct")
+	}
+	v = v.Elem()
+	if v.Kind() != reflect.Struct {
+		return fmt.Errorf("expected pointer to struct")
+	}
+
+	t := v.Type()
+	for i := 0; i < v.NumField(); i++ {
+		field := t.Field(i)
+		tag := field.Tag.Get("jm")
+		if tag == "" || tag == "-" {
+			continue
+		}
+		if val, ok := data[tag]; ok {
+			fieldVal := v.Field(i)
+			if fieldVal.CanSet() {
+				valRef := reflect.ValueOf(val)
+				if valRef.Type().ConvertibleTo(fieldVal.Type()) {
+					fieldVal.Set(valRef.Convert(fieldVal.Type()))
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func FillFromJM(target any, data any) error {
+	targetVal := reflect.ValueOf(target)
+	if targetVal.Kind() != reflect.Ptr || targetVal.IsNil() {
+		return fmt.Errorf("target must be a non-nil pointer")
+	}
+
+	elemVal := targetVal.Elem()
+	log.Println()
+
+	switch elemVal.Kind() {
+	case reflect.Struct:
+		// Single struct
+		switch data := data.(type) {
+		case Map:
+			return FillStructFromMap(target, map[string]any(data))
+		case map[string]any:
+			return FillStructFromMap(target, data)
+		default:
+			return fmt.Errorf("data must be map[string]any for struct input")
+		}
+	case reflect.Slice:
+		// Slice of structs or pointers to structs
+		maps, ok := data.([]map[string]any)
+		if !ok {
+			return fmt.Errorf("data must be []map[string]any for slice input")
+		}
+
+		sliceType := elemVal.Type()
+		elemType := sliceType.Elem()
+
+		for _, m := range maps {
+			var newElem reflect.Value
+			if elemType.Kind() == reflect.Ptr && elemType.Elem().Kind() == reflect.Struct {
+				// []*Struct
+				newPtr := reflect.New(elemType.Elem())
+				if err := FillStructFromMap(newPtr.Interface(), m); err != nil {
+					return err
+				}
+				newElem = newPtr
+			} else if elemType.Kind() == reflect.Struct {
+				// []Struct
+				newStruct := reflect.New(elemType)
+				if err := FillStructFromMap(newStruct.Interface(), m); err != nil {
+					return err
+				}
+				newElem = newStruct.Elem()
+			} else {
+				return fmt.Errorf("unsupported slice element type: %v", elemType.Kind())
+			}
+
+			elemVal.Set(reflect.Append(elemVal, newElem))
+		}
+		return nil
+
+	default:
+		return fmt.Errorf("target must be pointer to struct or slice")
+	}
+}