map_utils.go raw

   1  package dotenv
   2  
   3  import (
   4  	"strings"
   5  
   6  	"github.com/spf13/cast"
   7  )
   8  
   9  // flattenAndMergeMap recursively flattens the given map into a new map
  10  // Code is based on the function with the same name in the main package.
  11  // TODO: move it to a common place.
  12  func flattenAndMergeMap(shadow, m map[string]any, prefix, delimiter string) map[string]any {
  13  	if shadow != nil && prefix != "" && shadow[prefix] != nil {
  14  		// prefix is shadowed => nothing more to flatten
  15  		return shadow
  16  	}
  17  	if shadow == nil {
  18  		shadow = make(map[string]any)
  19  	}
  20  
  21  	var m2 map[string]any
  22  	if prefix != "" {
  23  		prefix += delimiter
  24  	}
  25  	for k, val := range m {
  26  		fullKey := prefix + k
  27  		switch val := val.(type) {
  28  		case map[string]any:
  29  			m2 = val
  30  		case map[any]any:
  31  			m2 = cast.ToStringMap(val)
  32  		default:
  33  			// immediate value
  34  			shadow[strings.ToLower(fullKey)] = val
  35  			continue
  36  		}
  37  		// recursively merge to shadow map
  38  		shadow = flattenAndMergeMap(shadow, m2, fullKey, delimiter)
  39  	}
  40  	return shadow
  41  }
  42