env.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package config
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. "github.com/go-kratos/kratos/v2/config"
  7. "github.com/go-kratos/kratos/v2/config/env"
  8. )
  9. type EnvSource struct {
  10. Prefixes []string
  11. }
  12. func (e *EnvSource) NewSource() (config.Source, error) {
  13. source := env.NewSource(e.Prefixes...)
  14. return source, nil
  15. }
  16. func (e *EnvSource) Validate() bool {
  17. if len(e.Prefixes) == 0 {
  18. return false
  19. }
  20. return true
  21. }
  22. func (e *EnvSource) String() string {
  23. return fmt.Sprintf("env source prefixes:%v", e.Prefixes)
  24. }
  25. // buildNestedMap 将环境变量的键值对转换为嵌套的 map 结构
  26. // 例如: "SERVER_PORT" -> "8080" 转换为 {"server": {"port": "8080"}}
  27. func buildNestedMap(key, value string) map[string]any {
  28. result := make(map[string]any)
  29. current := result
  30. // 将大写的键名转换为小写,并用下划线分割
  31. parts := strings.Split(strings.ToLower(key), "_")
  32. // 构建嵌套结构
  33. for i, part := range parts {
  34. if i == len(parts)-1 {
  35. // 最后一个部分,设置值
  36. current[part] = convertEnvValue(value)
  37. } else {
  38. // 中间部分,创建嵌套 map
  39. if _, exists := current[part]; !exists {
  40. current[part] = make(map[string]any)
  41. }
  42. current = current[part].(map[string]any)
  43. }
  44. }
  45. return result
  46. }
  47. // convertEnvValue 尝试将环境变量的字符串值转换为合适的类型
  48. func convertEnvValue(value string) any {
  49. // 布尔值转换
  50. if value == "true" {
  51. return true
  52. }
  53. if value == "false" {
  54. return false
  55. }
  56. // 整数转换
  57. if i, err := strconv.Atoi(value); err == nil {
  58. return i
  59. }
  60. // 浮点数转换
  61. if f, err := strconv.ParseFloat(value, 64); err == nil {
  62. return f
  63. }
  64. // 默认返回字符串
  65. return value
  66. }