serialize.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package rest
  2. import (
  3. "io"
  4. "log"
  5. "reflect"
  6. "strings"
  7. "git.ali33.ru/fcg-xvii/go-tools/json"
  8. )
  9. func findFileKey(m map[string]io.ReadCloser, key string) (io.Reader, bool) {
  10. key = camelToSnake(key)
  11. for fKey, val := range m {
  12. fKey = strings.Replace(fKey, ".", "_", -1)
  13. if key == fKey {
  14. return val, true
  15. }
  16. }
  17. return nil, false
  18. }
  19. func findKey(m map[string]any, key string) (val any, check bool) {
  20. if val, check = m[key]; !check {
  21. if !check {
  22. key = camelToSnake(key)
  23. val, check = m[key]
  24. }
  25. }
  26. return val, check
  27. }
  28. func serializeRequest(obj any, data json.Map, files map[string]io.ReadCloser, parent string) IErrorArgs {
  29. data.LogPretty()
  30. val := reflect.ValueOf(obj)
  31. if val.Kind() != reflect.Ptr {
  32. return NewErrPrtexpected(parent)
  33. }
  34. el := val.Elem()
  35. for i := 0; i < el.NumField(); i++ {
  36. required, isFile, arrived := false, false, false
  37. field := el.Type().Field(i)
  38. log.Println("------>", field)
  39. xField := el.Field(i)
  40. tag := field.Tag.Get("rest")
  41. if len(tag) > 0 {
  42. required = strings.Contains(tag, "required")
  43. isFile = strings.Contains(tag, "file")
  44. }
  45. if isFile {
  46. if f, check := findFileKey(files, field.Name); check {
  47. xField.Set(reflect.ValueOf(f))
  48. arrived = true
  49. }
  50. } else {
  51. if cval, check := findKey(data, field.Name); check {
  52. rVal := reflect.ValueOf(cval)
  53. switch {
  54. case xField.Kind() == reflect.Ptr:
  55. if rVal.Kind() != reflect.Map {
  56. return NewErrFieldType(field.Name, xField.Type().String(), rVal.String(), "expected json object")
  57. }
  58. rv := reflect.New(xField.Type().Elem())
  59. m := rVal.Convert(reflect.TypeOf(json.Map{})).Interface()
  60. if err := serializeRequest(rv.Interface(), m.(json.Map), files, field.Name); err != nil {
  61. return err
  62. }
  63. xField.Set(rv)
  64. default:
  65. if rVal.CanConvert(xField.Type()) {
  66. xField.Set(rVal.Convert(xField.Type()))
  67. } else {
  68. return NewErrFieldType(field.Name, xField.Type().String(), rVal.Kind().String(), "convert error")
  69. }
  70. }
  71. arrived = true
  72. }
  73. }
  74. if required && !arrived {
  75. return NewErrFieldRequired(field.Name)
  76. }
  77. }
  78. return nil
  79. }