fielder.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package rest
  2. import (
  3. "errors"
  4. "fmt"
  5. "reflect"
  6. "git.ali33.ru/fcg-xvii/go-tools/json"
  7. )
  8. type IFielder interface {
  9. Fields(...any) (json.Map, error)
  10. }
  11. type IFieldChecker interface {
  12. FieldCheck(string) bool
  13. }
  14. /////////////////////////////////////////////////
  15. func NewFielder(source any) *Fielder {
  16. res := &Fielder{
  17. source: source,
  18. fields: make(map[string]reflect.Value),
  19. }
  20. res._Prepare()
  21. return res
  22. }
  23. type Fielder struct {
  24. source any
  25. fields map[string]reflect.Value
  26. checker IFieldChecker
  27. }
  28. func (s *Fielder) _Prepare() {
  29. s.checker, _ = s.source.(IFieldChecker)
  30. val := reflect.ValueOf(s.source).Elem()
  31. for i := 0; i < val.NumField(); i++ {
  32. fName := val.Type().Field(i)
  33. field := val.Field(i)
  34. s.fields[CamelToSnake(fName.Name)] = field
  35. }
  36. }
  37. func (s *Fielder) Fields(names ...any) (json.Map, error) {
  38. res := make(json.Map)
  39. for _, rName := range names {
  40. var name string
  41. var fields []any
  42. if sName, check := rName.(string); check {
  43. name = sName
  44. } else if sMap, check := rName.(map[string]any); check {
  45. name = fmt.Sprint(sMap["name"])
  46. if rFields, check := sMap["fields"]; check {
  47. if rxFields, check := rFields.([]any); check {
  48. fields = rxFields
  49. }
  50. }
  51. }
  52. permission := true
  53. if s.checker != nil {
  54. permission = s.checker.FieldCheck(name)
  55. }
  56. val, check := s.fields[name]
  57. if check && permission {
  58. iface := val.Interface()
  59. if val.Kind() == reflect.Ptr {
  60. if val.IsNil() {
  61. res[name] = nil
  62. } else {
  63. if fielder, check := iface.(IFielder); check {
  64. xVal, err := fielder.Fields(fields...)
  65. if err != nil {
  66. return nil, err
  67. }
  68. res[name] = xVal
  69. }
  70. }
  71. } else {
  72. res[name] = val.Interface()
  73. }
  74. } else {
  75. return nil, errors.New(name)
  76. }
  77. }
  78. return res, nil
  79. }