struct2map.go 922 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package parser
  2. import (
  3. "reflect"
  4. "unicode"
  5. )
  6. func StructToMap(data interface{}) map[string]interface{} {
  7. result := make(map[string]interface{})
  8. val := reflect.ValueOf(data)
  9. if val.Kind() == reflect.Ptr {
  10. val = val.Elem()
  11. }
  12. for i := 0; i < val.NumField(); i++ {
  13. field := val.Field(i)
  14. typeField := val.Type().Field(i)
  15. fieldName := toSnakeCase(typeField.Name)
  16. if typeField.Anonymous {
  17. embeddedFields := StructToMap(field.Interface())
  18. for k, v := range embeddedFields {
  19. result[k] = v
  20. }
  21. } else {
  22. result[fieldName] = field.Interface()
  23. }
  24. }
  25. return result
  26. }
  27. func toSnakeCase(str string) string {
  28. runes := []rune(str)
  29. length := len(runes)
  30. var out []rune
  31. for i := 0; i < length; i++ {
  32. if unicode.IsUpper(runes[i]) {
  33. if i > 0 {
  34. out = append(out, '_')
  35. }
  36. out = append(out, unicode.ToLower(runes[i]))
  37. } else {
  38. out = append(out, runes[i])
  39. }
  40. }
  41. return string(out)
  42. }