github.com/aacfactory/avro@v1.2.12/internal/base/resolver.go (about) 1 package base 2 3 import ( 4 "fmt" 5 "math/big" 6 "sync" 7 "time" 8 9 "github.com/modern-go/reflect2" 10 ) 11 12 // TypeResolver resolves types by name. 13 type TypeResolver struct { 14 names sync.Map // map[string]reflect2.Type 15 types sync.Map // map[int][]string 16 } 17 18 // NewTypeResolver creates a new type resolver with all primitive types 19 // registered. 20 func NewTypeResolver() *TypeResolver { 21 r := &TypeResolver{} 22 23 // Register basic types 24 r.Register(string(Null), &null{}) 25 r.Register(string(Int), int8(0)) 26 r.Register(string(Int), int16(0)) 27 r.Register(string(Int), int32(0)) 28 r.Register(string(Int), int(0)) 29 r.Register(string(Long), int64(0)) 30 r.Register(string(Float), float32(0)) 31 r.Register(string(Double), float64(0)) 32 r.Register(string(String), "") 33 r.Register(string(Bytes), []byte{}) 34 r.Register(string(Boolean), true) 35 36 // Register logical types 37 r.Register(string(Int)+"."+string(Date), time.Time{}) 38 r.Register(string(Int)+"."+string(TimeMillis), time.Duration(0)) 39 r.Register(string(Long)+"."+string(TimestampMillis), time.Time{}) 40 r.Register(string(Long)+"."+string(TimestampMicros), time.Time{}) 41 r.Register(string(Long)+"."+string(TimeMicros), time.Duration(0)) 42 r.Register(string(Bytes)+"."+string(Decimal), big.NewRat(1, 1)) 43 r.Register(string(String)+"."+string(UUID), "") 44 45 return r 46 } 47 48 // Register registers names to their types for resolution. 49 func (r *TypeResolver) Register(name string, obj any) { 50 typ := reflect2.TypeOf(obj) 51 rtype := typ.RType() 52 53 r.names.Store(name, typ) 54 55 raw, ok := r.types.LoadOrStore(rtype, []string{name}) 56 if !ok { 57 return 58 } 59 names := raw.([]string) 60 names = append(names, name) 61 r.types.Store(rtype, names) 62 } 63 64 // Name gets the name for a type, or an error. 65 func (r *TypeResolver) Name(typ reflect2.Type) ([]string, error) { 66 rtype := typ.RType() 67 68 names, ok := r.types.Load(rtype) 69 if !ok { 70 return nil, fmt.Errorf("avro: unable to resolve type %s", typ.String()) 71 } 72 73 return names.([]string), nil 74 } 75 76 // Type gets the type for a name, or an error. 77 func (r *TypeResolver) Type(name string) (reflect2.Type, error) { 78 typ, ok := r.names.Load(name) 79 if !ok { 80 return nil, fmt.Errorf("avro: unable to resolve type with name %s", name) 81 } 82 83 return typ.(reflect2.Type), nil 84 } 85 86 // Register registers names to their types for resolution. All primitive types are pre-registered. 87 func Register(name string, obj any) { 88 DefaultConfig.Register(name, obj) 89 }