registry.go 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package json
  2. import (
  3. "reflect"
  4. "sync"
  5. "github.com/pkg/errors"
  6. )
  7. type Registry struct {
  8. mu *sync.RWMutex
  9. data map[string]reflect.Type
  10. }
  11. func NewRegistry() *Registry {
  12. return &Registry{
  13. mu: &sync.RWMutex{},
  14. data: make(map[string]reflect.Type),
  15. }
  16. }
  17. func (r *Registry) Register(name string, object interface{}) {
  18. if object == nil {
  19. r.mu.Lock()
  20. defer r.mu.Unlock()
  21. delete(r.data, name)
  22. return
  23. }
  24. typ := reflect.TypeOf(object)
  25. r.mu.Lock()
  26. defer r.mu.Unlock()
  27. r.data[name] = typ
  28. }
  29. func (r *Registry) Decode(dec *Decoder, name string) (interface{}, error) {
  30. r.mu.RLock()
  31. defer r.mu.RUnlock()
  32. if typ, ok := r.data[name]; ok {
  33. ptr := reflect.New(typ).Interface()
  34. if err := dec.Decode(ptr); err != nil {
  35. return nil, errors.Wrapf(err, `failed to decode field %s`, name)
  36. }
  37. return reflect.ValueOf(ptr).Elem().Interface(), nil
  38. }
  39. var decoded interface{}
  40. if err := dec.Decode(&decoded); err != nil {
  41. return nil, errors.Wrapf(err, `failed to decode field %s`, name)
  42. }
  43. return decoded, nil
  44. }