github.com/moqsien/xraycore@v1.8.5/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 }