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