github.com/imannamdari/v2ray-core/v5@v5.0.5/infra/conf/cfgcommon/loader/loader.go (about)

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