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  }