fork download
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "reflect"
  6. )
  7.  
  8. type Config struct {
  9. AppName string `json:"app_name"`
  10. Port int `json:"port"`
  11. Debug bool `json:"debug"`
  12. }
  13.  
  14. // LoadConfigFromMap loads configuration from a map[string]interface{}
  15. func LoadConfigFromMap(cfg interface{}, data map[string]interface{}) {
  16. v := reflect.ValueOf(cfg).Elem()
  17. for key, value := range data {
  18. field := v.FieldByName(key)
  19. if field.IsValid() && field.CanSet() {
  20. if field.Kind() == reflect.Ptr {
  21. if field.IsNil() {
  22. field.Set(reflect.New(field.Type().Elem()))
  23. }
  24. field = field.Elem()
  25. }
  26.  
  27. valueType := reflect.TypeOf(value)
  28. if field.Kind() == valueType.Kind() {
  29. field.Set(reflect.ValueOf(value))
  30. } else if field.Kind() == reflect.Struct {
  31. // Recursively call LoadConfigFromMap if the field is a struct
  32. LoadConfigFromMap(field.Addr().Interface(), value.(map[string]interface{}))
  33. }
  34. }
  35. }
  36. }
  37.  
  38. func main() {
  39. cfg := &Config{}
  40. configData := map[string]interface{}{
  41. "app_name": "MyApp",
  42. "port": 8080,
  43. "debug": true,
  44. "db": map[string]interface{}{
  45. "host": "localhost",
  46. "port": 3306,
  47. },
  48. }
  49.  
  50. LoadConfigFromMap(cfg, configData)
  51.  
  52. fmt.Printf("%#v\n", cfg)
  53. }
Success #stdin #stdout 0s 5288KB
stdin
Standard input is empty
stdout
&main.Config{AppName:"", Port:0, Debug:false}