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 }