loader.go 1.9 KB

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