github.com/lyft/flytestdlib@v0.3.12-0.20210213045714-8cdd111ecda1/config/utils.go (about)

     1  package config
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  
     8  	"github.com/pkg/errors"
     9  
    10  	stdLibErrs "github.com/lyft/flytestdlib/errors"
    11  )
    12  
    13  // Uses Json marshal/unmarshal to make a deep copy of a config object.
    14  func DeepCopyConfig(config Config) (Config, error) {
    15  	raw, err := json.Marshal(config)
    16  	if err != nil {
    17  		return nil, err
    18  	}
    19  
    20  	t := reflect.TypeOf(config)
    21  	ptrValue := reflect.New(t)
    22  	newObj := ptrValue.Interface()
    23  	if err = json.Unmarshal(raw, newObj); err != nil {
    24  		return nil, err
    25  	}
    26  
    27  	return ptrValue.Elem().Interface(), nil
    28  }
    29  
    30  func DeepEqual(config1, config2 Config) bool {
    31  	return reflect.DeepEqual(config1, config2)
    32  }
    33  
    34  func toInterface(config Config) (interface{}, error) {
    35  	raw, err := json.Marshal(config)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	var m interface{}
    41  	err = json.Unmarshal(raw, &m)
    42  	return m, err
    43  }
    44  
    45  // Builds a generic map out of the root section config and its sub-sections configs.
    46  func AllConfigsAsMap(root Section) (m map[string]interface{}, err error) {
    47  	errs := stdLibErrs.ErrorCollection{}
    48  	allConfigs := make(map[string]interface{}, len(root.GetSections()))
    49  	if root.GetConfig() != nil {
    50  		rootConfig, err := toInterface(root.GetConfig())
    51  		if !errs.Append(err) {
    52  			if asMap, isCasted := rootConfig.(map[string]interface{}); isCasted {
    53  				allConfigs = asMap
    54  			} else {
    55  				allConfigs[""] = rootConfig
    56  			}
    57  		}
    58  	}
    59  
    60  	for k, section := range root.GetSections() {
    61  		if _, alreadyExists := allConfigs[k]; alreadyExists {
    62  			errs.Append(errors.Wrap(ErrChildConfigOverridesConfig,
    63  				fmt.Sprintf("section key [%v] overrides an existing native config property", k)))
    64  		}
    65  
    66  		allConfigs[k], err = AllConfigsAsMap(section)
    67  		errs.Append(err)
    68  	}
    69  
    70  	return allConfigs, errs.ErrorOrDefault()
    71  }