github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/infra/conf/loader.go (about)

     1  package conf
     2  
     3  import (
     4  	"encoding/json"
     5  	"strings"
     6  )
     7  
     8  type ConfigCreator func() interface{}
     9  
    10  type ConfigCreatorCache map[string]ConfigCreator
    11  
    12  func (v ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) error {
    13  	if _, found := v[id]; found {
    14  		return newError(id, " already registered.").AtError()
    15  	}
    16  
    17  	v[id] = creator
    18  	return nil
    19  }
    20  
    21  func (v ConfigCreatorCache) CreateConfig(id string) (interface{}, error) {
    22  	creator, found := v[id]
    23  	if !found {
    24  		return nil, newError("unknown config id: ", id)
    25  	}
    26  	return creator(), nil
    27  }
    28  
    29  type JSONConfigLoader struct {
    30  	cache     ConfigCreatorCache
    31  	idKey     string
    32  	configKey string
    33  }
    34  
    35  func NewJSONConfigLoader(cache ConfigCreatorCache, idKey string, configKey string) *JSONConfigLoader {
    36  	return &JSONConfigLoader{
    37  		idKey:     idKey,
    38  		configKey: configKey,
    39  		cache:     cache,
    40  	}
    41  }
    42  
    43  func (v *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) {
    44  	id = strings.ToLower(id)
    45  	config, err := v.cache.CreateConfig(id)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	if err := json.Unmarshal(raw, config); err != nil {
    50  		return nil, err
    51  	}
    52  	return config, nil
    53  }
    54  
    55  func (v *JSONConfigLoader) Load(raw []byte) (interface{}, string, error) {
    56  	var obj map[string]json.RawMessage
    57  	if err := json.Unmarshal(raw, &obj); err != nil {
    58  		return nil, "", err
    59  	}
    60  	rawID, found := obj[v.idKey]
    61  	if !found {
    62  		return nil, "", newError(v.idKey, " not found in JSON context").AtError()
    63  	}
    64  	var id string
    65  	if err := json.Unmarshal(rawID, &id); err != nil {
    66  		return nil, "", err
    67  	}
    68  	rawConfig := json.RawMessage(raw)
    69  	if len(v.configKey) > 0 {
    70  		configValue, found := obj[v.configKey]
    71  		if found {
    72  			rawConfig = configValue
    73  		} else {
    74  			// Default to empty json object.
    75  			rawConfig = json.RawMessage([]byte("{}"))
    76  		}
    77  	}
    78  	config, err := v.LoadWithID([]byte(rawConfig), id)
    79  	if err != nil {
    80  		return nil, id, err
    81  	}
    82  	return config, id, nil
    83  }