jm.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package json
  2. import (
  3. "fmt"
  4. "log"
  5. "reflect"
  6. )
  7. // Заполняет поля структуры из map по тегам `jm`
  8. func FillStructFromMap(ptr any, data map[string]any) error {
  9. v := reflect.ValueOf(ptr)
  10. if v.Kind() != reflect.Ptr || v.IsNil() {
  11. return fmt.Errorf("expected pointer to struct")
  12. }
  13. v = v.Elem()
  14. if v.Kind() != reflect.Struct {
  15. return fmt.Errorf("expected pointer to struct")
  16. }
  17. t := v.Type()
  18. for i := 0; i < v.NumField(); i++ {
  19. field := t.Field(i)
  20. tag := field.Tag.Get("jm")
  21. if tag == "" || tag == "-" {
  22. continue
  23. }
  24. if val, ok := data[tag]; ok {
  25. fieldVal := v.Field(i)
  26. if fieldVal.CanSet() {
  27. valRef := reflect.ValueOf(val)
  28. if valRef.Type().ConvertibleTo(fieldVal.Type()) {
  29. fieldVal.Set(valRef.Convert(fieldVal.Type()))
  30. }
  31. }
  32. }
  33. }
  34. return nil
  35. }
  36. func FillFromJM(target any, data any) error {
  37. targetVal := reflect.ValueOf(target)
  38. if targetVal.Kind() != reflect.Ptr || targetVal.IsNil() {
  39. return fmt.Errorf("target must be a non-nil pointer")
  40. }
  41. elemVal := targetVal.Elem()
  42. log.Println()
  43. switch elemVal.Kind() {
  44. case reflect.Struct:
  45. // Single struct
  46. switch data := data.(type) {
  47. case Map:
  48. return FillStructFromMap(target, map[string]any(data))
  49. case map[string]any:
  50. return FillStructFromMap(target, data)
  51. default:
  52. return fmt.Errorf("data must be map[string]any for struct input")
  53. }
  54. case reflect.Slice:
  55. // Slice of structs or pointers to structs
  56. maps, ok := data.([]map[string]any)
  57. if !ok {
  58. return fmt.Errorf("data must be []map[string]any for slice input")
  59. }
  60. sliceType := elemVal.Type()
  61. elemType := sliceType.Elem()
  62. for _, m := range maps {
  63. var newElem reflect.Value
  64. if elemType.Kind() == reflect.Ptr && elemType.Elem().Kind() == reflect.Struct {
  65. // []*Struct
  66. newPtr := reflect.New(elemType.Elem())
  67. if err := FillStructFromMap(newPtr.Interface(), m); err != nil {
  68. return err
  69. }
  70. newElem = newPtr
  71. } else if elemType.Kind() == reflect.Struct {
  72. // []Struct
  73. newStruct := reflect.New(elemType)
  74. if err := FillStructFromMap(newStruct.Interface(), m); err != nil {
  75. return err
  76. }
  77. newElem = newStruct.Elem()
  78. } else {
  79. return fmt.Errorf("unsupported slice element type: %v", elemType.Kind())
  80. }
  81. elemVal.Set(reflect.Append(elemVal, newElem))
  82. }
  83. return nil
  84. default:
  85. return fmt.Errorf("target must be pointer to struct or slice")
  86. }
  87. }