@@ -81,142 +81,3 @@ func getNilOrZeroValue[T any]() T {
8181 // Otherwise return zero value
8282 return result
8383}
84-
85- // init registers the gobValue wrapper type with gob for gobSerializer
86- func init () {
87- // Register wrapper type - this is required for gob encoding/decoding to work
88- safeGobRegister (gobValue {})
89- }
90-
91- type gobSerializer [T any ] struct {}
92-
93- func newGobSerializer [T any ]() serializer [T ] {
94- return & gobSerializer [T ]{}
95- }
96-
97- func (g * gobSerializer [T ]) Encode (data T ) (string , error ) {
98- if isNilValue (data ) {
99- // For nil values, encode an empty byte slice directly to base64
100- return base64 .StdEncoding .EncodeToString ([]byte {}), nil
101- }
102-
103- // Register the type before encoding
104- safeGobRegister (data )
105-
106- var buf bytes.Buffer
107- encoder := gob .NewEncoder (& buf )
108- wrapper := gobValue {Value : data }
109- if err := encoder .Encode (wrapper ); err != nil {
110- return "" , fmt .Errorf ("failed to encode data: %w" , err )
111- }
112- return base64 .StdEncoding .EncodeToString (buf .Bytes ()), nil
113- }
114-
115- func (g * gobSerializer [T ]) Decode (data * string ) (T , error ) {
116- zero := * new (T )
117-
118- if data == nil || * data == "" {
119- return zero , nil
120- }
121-
122- dataBytes , err := base64 .StdEncoding .DecodeString (* data )
123- if err != nil {
124- return zero , fmt .Errorf ("failed to decode base64 data: %w" , err )
125- }
126-
127- // If decoded data is empty, it represents a nil value
128- if len (dataBytes ) == 0 {
129- return zero , nil
130- }
131-
132- // Resolve the type of T
133- tType := reflect .TypeOf (zero )
134- if tType == nil {
135- // zero is nil, T is likely a pointer type or interface
136- // Get the type from a pointer to T's zero value
137- tType = reflect .TypeOf (& zero ).Elem ()
138- }
139-
140- // Register type T before decoding
141- // This is required on the recovery path, where the process might not have been doing the encode/registering.
142- // This will panic if T is an non-registered interface type (which is not supported)
143- if tType != nil && tType .Kind () != reflect .Interface {
144- safeGobRegister (zero )
145- }
146-
147- var wrapper gobValue
148- decoder := gob .NewDecoder (bytes .NewReader (dataBytes ))
149- if err := decoder .Decode (& wrapper ); err != nil {
150- return zero , fmt .Errorf ("failed to decode gob data: %w" , err )
151- }
152-
153- decoded := wrapper .Value
154-
155- // Gob stores pointed values directly, so we need to reconstruct the pointer type
156- if tType != nil && tType .Kind () == reflect .Pointer {
157- elemType := tType .Elem ()
158- decodedType := reflect .TypeOf (decoded )
159-
160- // Check if decoded value matches the element type (not the pointer type)
161- if decodedType != nil && decodedType == elemType {
162- // Create a new pointer to the decoded value
163- elemValue := reflect .New (elemType )
164- elemValue .Elem ().Set (reflect .ValueOf (decoded ))
165- return elemValue .Interface ().(T ), nil
166- }
167- // If decoded is already a pointer of the correct type, try direct assertion
168- if decodedType != nil && decodedType == tType {
169- typedResult , ok := decoded .(T )
170- if ok {
171- return typedResult , nil
172- }
173- }
174- // If decoded is nil and T is a pointer type, return nil pointer
175- if decoded == nil {
176- return zero , nil
177- }
178- }
179-
180- // Not a pointer -- direct type assertion
181- typedResult , ok := decoded .(T )
182- if ! ok {
183- return zero , fmt .Errorf ("cannot convert decoded value of type %T to %T" , decoded , zero )
184- }
185- return typedResult , nil
186- }
187-
188- // isNilValue checks if a value is nil (for pointer types, slice, map, etc.)
189- func isNilValue (v any ) bool {
190- val := reflect .ValueOf (v )
191- if ! val .IsValid () {
192- return true
193- }
194- switch val .Kind () {
195- case reflect .Pointer , reflect .Slice , reflect .Map , reflect .Chan , reflect .Func :
196- return val .IsNil ()
197- }
198- return false
199- }
200-
201- // IsNestedPointer checks if a type is a nested pointer (e.g., **int, ***int).
202- // It returns false for non-pointer types and single-level pointers (*int).
203- // It returns true for nested pointers with depth > 1.
204- func IsNestedPointer (t reflect.Type ) bool {
205- if t == nil {
206- return false
207- }
208-
209- depth := 0
210- currentType := t
211-
212- // Count pointer indirection levels, break early if depth > 1
213- for currentType != nil && currentType .Kind () == reflect .Pointer {
214- depth ++
215- if depth > 1 {
216- return true
217- }
218- currentType = currentType .Elem ()
219- }
220-
221- return false
222- }
0 commit comments