@@ -42,7 +42,7 @@ func (e registryError) Error() string {
42
42
// ErrRegistry indicates an error returned by the [Registrar].
43
43
var ErrRegistry registryError = "JSON adapters registry error"
44
44
45
- type registry []ifaces.RegistryEntry
45
+ type registry []* ifaces.RegistryEntry
46
46
47
47
// Registrar holds registered [ifaces.Adapters] for different serialization capabilities.
48
48
//
@@ -57,54 +57,79 @@ type Registrar struct {
57
57
gmx sync.RWMutex
58
58
59
59
// cache indexed by value type, so we don't have to lookup
60
- marshalerCache map [reflect.Type ]ifaces.RegistryEntry
61
- unmarshalerCache map [reflect.Type ]ifaces.RegistryEntry
62
- orderedMarshalerCache map [reflect.Type ]ifaces.RegistryEntry
63
- orderedUnmarshalerCache map [reflect.Type ]ifaces.RegistryEntry
64
- orderedMapCache map [reflect.Type ]ifaces.RegistryEntry
60
+ marshalerCache map [reflect.Type ]* ifaces.RegistryEntry
61
+ unmarshalerCache map [reflect.Type ]* ifaces.RegistryEntry
62
+ orderedMarshalerCache map [reflect.Type ]* ifaces.RegistryEntry
63
+ orderedUnmarshalerCache map [reflect.Type ]* ifaces.RegistryEntry
64
+ orderedMapCache map [reflect.Type ]* ifaces.RegistryEntry
65
65
}
66
66
67
67
func NewRegistrar () * Registrar {
68
68
r := & Registrar {}
69
69
70
- r .marshalerCache = make (map [reflect.Type ]ifaces.RegistryEntry )
71
- r .unmarshalerCache = make (map [reflect.Type ]ifaces.RegistryEntry )
72
- r .orderedMarshalerCache = make (map [reflect.Type ]ifaces.RegistryEntry )
73
- r .orderedUnmarshalerCache = make (map [reflect.Type ]ifaces.RegistryEntry )
74
- r .orderedMapCache = make (map [reflect.Type ]ifaces.RegistryEntry )
70
+ r .marshalerRegistry = make (registry , 0 , 1 )
71
+ r .unmarshalerRegistry = make (registry , 0 , 1 )
72
+ r .orderedMarshalerRegistry = make (registry , 0 , 1 )
73
+ r .orderedUnmarshalerRegistry = make (registry , 0 , 1 )
74
+ r .orderedMapRegistry = make (registry , 0 , 1 )
75
+
76
+ r .marshalerCache = make (map [reflect.Type ]* ifaces.RegistryEntry )
77
+ r .unmarshalerCache = make (map [reflect.Type ]* ifaces.RegistryEntry )
78
+ r .orderedMarshalerCache = make (map [reflect.Type ]* ifaces.RegistryEntry )
79
+ r .orderedUnmarshalerCache = make (map [reflect.Type ]* ifaces.RegistryEntry )
80
+ r .orderedMapCache = make (map [reflect.Type ]* ifaces.RegistryEntry )
75
81
76
82
defaultRegistered (r )
77
83
78
84
return r
79
85
}
80
86
87
+ // ClearCache resets the internal type cache.
88
+ func (r * Registrar ) ClearCache () {
89
+ r .gmx .Lock ()
90
+ r .clearCache ()
91
+ r .gmx .Unlock ()
92
+ }
93
+
94
+ // Reset the [Registrar] to its defaults.
95
+ func (r * Registrar ) Reset () {
96
+ r .gmx .Lock ()
97
+ r .clearCache ()
98
+ r .marshalerRegistry = r .marshalerRegistry [:0 ]
99
+ r .unmarshalerRegistry = r .unmarshalerRegistry [:0 ]
100
+ r .orderedMarshalerRegistry = r .orderedMarshalerRegistry [:0 ]
101
+ r .orderedUnmarshalerRegistry = r .orderedUnmarshalerRegistry [:0 ]
102
+ r .orderedMapRegistry = r .orderedMapRegistry [:0 ]
103
+ r .gmx .Unlock ()
104
+ }
105
+
81
106
// RegisterFor registers an adapter for some JSON capabilities.
82
107
func (r * Registrar ) RegisterFor (entry ifaces.RegistryEntry ) {
83
108
r .gmx .Lock ()
84
109
if entry .What .Has (ifaces .CapabilityMarshalJSON ) {
85
110
e := entry
86
111
e .What &= ifaces .Capabilities (ifaces .CapabilityMarshalJSON )
87
- r .marshalerRegistry = slices .Insert (r .marshalerRegistry , 0 , e )
112
+ r .marshalerRegistry = slices .Insert (r .marshalerRegistry , 0 , & e )
88
113
}
89
114
if entry .What .Has (ifaces .CapabilityUnmarshalJSON ) {
90
115
e := entry
91
116
e .What &= ifaces .Capabilities (ifaces .CapabilityUnmarshalJSON )
92
- r .unmarshalerRegistry = slices .Insert (r .unmarshalerRegistry , 0 , e )
117
+ r .unmarshalerRegistry = slices .Insert (r .unmarshalerRegistry , 0 , & e )
93
118
}
94
119
if entry .What .Has (ifaces .CapabilityOrderedMarshalJSON ) {
95
120
e := entry
96
121
e .What &= ifaces .Capabilities (ifaces .CapabilityOrderedMarshalJSON )
97
- r .orderedMarshalerRegistry = slices .Insert (r .orderedMarshalerRegistry , 0 , e )
122
+ r .orderedMarshalerRegistry = slices .Insert (r .orderedMarshalerRegistry , 0 , & e )
98
123
}
99
124
if entry .What .Has (ifaces .CapabilityOrderedUnmarshalJSON ) {
100
125
e := entry
101
126
e .What &= ifaces .Capabilities (ifaces .CapabilityOrderedUnmarshalJSON )
102
- r .orderedUnmarshalerRegistry = slices .Insert (r .orderedUnmarshalerRegistry , 0 , e )
127
+ r .orderedUnmarshalerRegistry = slices .Insert (r .orderedUnmarshalerRegistry , 0 , & e )
103
128
}
104
129
if entry .What .Has (ifaces .CapabilityOrderedMap ) {
105
130
e := entry
106
131
e .What &= ifaces .Capabilities (ifaces .CapabilityOrderedMap )
107
- r .orderedMapRegistry = slices .Insert (r .orderedMapRegistry , 0 , e )
132
+ r .orderedMapRegistry = slices .Insert (r .orderedMapRegistry , 0 , & e )
108
133
}
109
134
r .gmx .Unlock ()
110
135
}
@@ -119,16 +144,22 @@ func (r *Registrar) AdapterFor(capability ifaces.Capability, value any) (ifaces.
119
144
return nil , noopRedeemer
120
145
}
121
146
122
- adapter := entry .Constructor ()
123
- if entry .Redeemer != nil {
124
- return adapter , func () {
125
- entry .Redeemer (adapter )
126
- }
147
+ adapter , redeem := entry .Constructor ()
148
+ if redeem != nil {
149
+ return adapter , redeem
127
150
}
128
151
129
152
return adapter , noopRedeemer
130
153
}
131
154
155
+ func (r * Registrar ) clearCache () {
156
+ clear (r .marshalerCache )
157
+ clear (r .unmarshalerCache )
158
+ clear (r .orderedMarshalerCache )
159
+ clear (r .orderedUnmarshalerCache )
160
+ clear (r .orderedMapCache )
161
+ }
162
+
132
163
func (r * Registrar ) findFirstFor (capability ifaces.Capability , value any ) * ifaces.RegistryEntry {
133
164
switch capability {
134
165
case ifaces .CapabilityMarshalJSON :
@@ -146,13 +177,13 @@ func (r *Registrar) findFirstFor(capability ifaces.Capability, value any) *iface
146
177
}
147
178
}
148
179
149
- func (r * Registrar ) findFirstInRegistryFor (reg registry , cache map [reflect.Type ]ifaces.RegistryEntry , capability ifaces.Capability , value any ) * ifaces.RegistryEntry {
180
+ func (r * Registrar ) findFirstInRegistryFor (reg registry , cache map [reflect.Type ]* ifaces.RegistryEntry , capability ifaces.Capability , value any ) * ifaces.RegistryEntry {
150
181
r .gmx .RLock ()
151
182
if len (reg ) > 1 {
152
183
if entry , ok := cache [reflect .TypeOf (value )]; ok {
153
184
// cache hit
154
185
r .gmx .RUnlock ()
155
- return & entry
186
+ return entry
156
187
}
157
188
}
158
189
@@ -168,7 +199,7 @@ func (r *Registrar) findFirstInRegistryFor(reg registry, cache map[reflect.Type]
168
199
cache [reflect .TypeOf (value )] = entry
169
200
r .gmx .Unlock ()
170
201
171
- return & entry
202
+ return entry
172
203
}
173
204
174
205
// no adapter found
0 commit comments