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