@@ -237,6 +237,291 @@ func mergeObjects(obj1, obj2 map[string]interface{}) map[string]interface{} {
237237 return merged
238238}
239239
240+ // FlexibleUnmarshal performs flexible JSON unmarshal that handles type mismatches
241+ func FlexibleUnmarshal (data []byte , v interface {}) error {
242+ // First try normal unmarshal
243+ if err := json .Unmarshal (data , v ); err == nil {
244+ return nil
245+ }
246+
247+ // If normal unmarshal fails, try flexible unmarshal
248+ var rawData map [string ]interface {}
249+ if err := json .Unmarshal (data , & rawData ); err != nil {
250+ return err
251+ }
252+
253+ return flexibleMapToStruct (rawData , v )
254+ }
255+
256+ // flexibleMapToStruct converts map to struct with flexible type handling
257+ func flexibleMapToStruct (data map [string ]interface {}, v interface {}) error {
258+ rv := reflect .ValueOf (v )
259+ if rv .Kind () != reflect .Ptr || rv .IsNil () {
260+ return fmt .Errorf ("destination must be a non-nil pointer" )
261+ }
262+
263+ rv = rv .Elem ()
264+ if rv .Kind () != reflect .Struct {
265+ return fmt .Errorf ("destination must be a pointer to struct" )
266+ }
267+
268+ rt := rv .Type ()
269+ for i := 0 ; i < rv .NumField (); i ++ {
270+ field := rv .Field (i )
271+ fieldType := rt .Field (i )
272+
273+ if ! field .CanSet () {
274+ continue
275+ }
276+
277+ jsonTag := fieldType .Tag .Get ("json" )
278+ if jsonTag == "" || jsonTag == "-" {
279+ continue
280+ }
281+
282+ tagParts := strings .Split (jsonTag , "," )
283+ fieldName := tagParts [0 ]
284+
285+ value , exists := data [fieldName ]
286+ if ! exists {
287+ continue
288+ }
289+
290+ if err := setFlexibleValue (field , value ); err != nil {
291+ return fmt .Errorf ("error setting field %s: %v" , fieldName , err )
292+ }
293+ }
294+
295+ return nil
296+ }
297+
298+ // setFlexibleValue sets value to field with flexible type conversion
299+ func setFlexibleValue (field reflect.Value , value interface {}) error {
300+ if value == nil {
301+ return nil
302+ }
303+
304+ targetType := field .Type ()
305+ sourceValue := reflect .ValueOf (value )
306+
307+ // Handle pointer types
308+ if targetType .Kind () == reflect .Ptr {
309+ if field .IsNil () {
310+ field .Set (reflect .New (targetType .Elem ()))
311+ }
312+ return setFlexibleValue (field .Elem (), value )
313+ }
314+
315+ // Handle same types
316+ if sourceValue .Type ().AssignableTo (targetType ) {
317+ field .Set (sourceValue )
318+ return nil
319+ }
320+
321+ // Handle conversions
322+ switch targetType .Kind () {
323+ case reflect .String :
324+ return setStringValue (field , value )
325+ case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :
326+ return setIntValue (field , value )
327+ case reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 :
328+ return setUintValue (field , value )
329+ case reflect .Float32 , reflect .Float64 :
330+ return setFloatValue (field , value )
331+ case reflect .Bool :
332+ return setBoolValue (field , value )
333+ case reflect .Slice :
334+ return setSliceValue (field , value )
335+ case reflect .Struct :
336+ return setStructValue (field , value )
337+ default :
338+ return fmt .Errorf ("unsupported type conversion from %T to %s" , value , targetType )
339+ }
340+ }
341+
342+ // setStringValue converts any value to string
343+ func setStringValue (field reflect.Value , value interface {}) error {
344+ switch v := value .(type ) {
345+ case string :
346+ field .SetString (v )
347+ case int , int8 , int16 , int32 , int64 :
348+ field .SetString (fmt .Sprintf ("%d" , v ))
349+ case uint , uint8 , uint16 , uint32 , uint64 :
350+ field .SetString (fmt .Sprintf ("%d" , v ))
351+ case float32 , float64 :
352+ field .SetString (fmt .Sprintf ("%g" , v ))
353+ case bool :
354+ field .SetString (fmt .Sprintf ("%t" , v ))
355+ default :
356+ field .SetString (fmt .Sprintf ("%v" , v ))
357+ }
358+ return nil
359+ }
360+
361+ // setIntValue converts any value to int
362+ func setIntValue (field reflect.Value , value interface {}) error {
363+ switch v := value .(type ) {
364+ case int :
365+ field .SetInt (int64 (v ))
366+ case int8 :
367+ field .SetInt (int64 (v ))
368+ case int16 :
369+ field .SetInt (int64 (v ))
370+ case int32 :
371+ field .SetInt (int64 (v ))
372+ case int64 :
373+ field .SetInt (v )
374+ case uint , uint8 , uint16 , uint32 , uint64 :
375+ field .SetInt (int64 (reflect .ValueOf (v ).Uint ()))
376+ case float32 :
377+ field .SetInt (int64 (v ))
378+ case float64 :
379+ field .SetInt (int64 (v ))
380+ case string :
381+ if i , err := strconv .ParseInt (v , 10 , 64 ); err == nil {
382+ field .SetInt (i )
383+ } else if f , err := strconv .ParseFloat (v , 64 ); err == nil {
384+ field .SetInt (int64 (f ))
385+ } else {
386+ return fmt .Errorf ("cannot convert string %q to int" , v )
387+ }
388+ default :
389+ return fmt .Errorf ("cannot convert %T to int" , v )
390+ }
391+ return nil
392+ }
393+
394+ // setUintValue converts any value to uint
395+ func setUintValue (field reflect.Value , value interface {}) error {
396+ switch v := value .(type ) {
397+ case uint :
398+ field .SetUint (uint64 (v ))
399+ case uint8 :
400+ field .SetUint (uint64 (v ))
401+ case uint16 :
402+ field .SetUint (uint64 (v ))
403+ case uint32 :
404+ field .SetUint (uint64 (v ))
405+ case uint64 :
406+ field .SetUint (v )
407+ case int , int8 , int16 , int32 , int64 :
408+ val := reflect .ValueOf (v ).Int ()
409+ if val < 0 {
410+ return fmt .Errorf ("cannot convert negative int %d to uint" , val )
411+ }
412+ field .SetUint (uint64 (val ))
413+ case float32 :
414+ if v < 0 {
415+ return fmt .Errorf ("cannot convert negative float %f to uint" , v )
416+ }
417+ field .SetUint (uint64 (v ))
418+ case float64 :
419+ if v < 0 {
420+ return fmt .Errorf ("cannot convert negative float %f to uint" , v )
421+ }
422+ field .SetUint (uint64 (v ))
423+ case string :
424+ if i , err := strconv .ParseUint (v , 10 , 64 ); err == nil {
425+ field .SetUint (i )
426+ } else if f , err := strconv .ParseFloat (v , 64 ); err == nil {
427+ if f < 0 {
428+ return fmt .Errorf ("cannot convert negative float %f to uint" , f )
429+ }
430+ field .SetUint (uint64 (f ))
431+ } else {
432+ return fmt .Errorf ("cannot convert string %q to uint" , v )
433+ }
434+ default :
435+ return fmt .Errorf ("cannot convert %T to uint" , v )
436+ }
437+ return nil
438+ }
439+
440+ // setFloatValue converts any value to float
441+ func setFloatValue (field reflect.Value , value interface {}) error {
442+ switch v := value .(type ) {
443+ case float32 :
444+ field .SetFloat (float64 (v ))
445+ case float64 :
446+ field .SetFloat (v )
447+ case int , int8 , int16 , int32 , int64 :
448+ field .SetFloat (float64 (reflect .ValueOf (v ).Int ()))
449+ case uint , uint8 , uint16 , uint32 , uint64 :
450+ field .SetFloat (float64 (reflect .ValueOf (v ).Uint ()))
451+ case string :
452+ if f , err := strconv .ParseFloat (v , 64 ); err == nil {
453+ field .SetFloat (f )
454+ } else {
455+ return fmt .Errorf ("cannot convert string %q to float" , v )
456+ }
457+ default :
458+ return fmt .Errorf ("cannot convert %T to float" , v )
459+ }
460+ return nil
461+ }
462+
463+ // setBoolValue converts any value to bool
464+ func setBoolValue (field reflect.Value , value interface {}) error {
465+ switch v := value .(type ) {
466+ case bool :
467+ field .SetBool (v )
468+ case string :
469+ if b , err := strconv .ParseBool (v ); err == nil {
470+ field .SetBool (b )
471+ } else {
472+ return fmt .Errorf ("cannot convert string %q to bool" , v )
473+ }
474+ case int , int8 , int16 , int32 , int64 :
475+ field .SetBool (reflect .ValueOf (v ).Int () != 0 )
476+ case uint , uint8 , uint16 , uint32 , uint64 :
477+ field .SetBool (reflect .ValueOf (v ).Uint () != 0 )
478+ case float32 , float64 :
479+ field .SetBool (reflect .ValueOf (v ).Float () != 0 )
480+ default :
481+ return fmt .Errorf ("cannot convert %T to bool" , v )
482+ }
483+ return nil
484+ }
485+
486+ // setSliceValue converts slice values
487+ func setSliceValue (field reflect.Value , value interface {}) error {
488+ sourceSlice := reflect .ValueOf (value )
489+ if sourceSlice .Kind () != reflect .Slice {
490+ return fmt .Errorf ("source is not a slice" )
491+ }
492+
493+ elementType := field .Type ().Elem ()
494+ newSlice := reflect .MakeSlice (field .Type (), sourceSlice .Len (), sourceSlice .Len ())
495+
496+ for i := 0 ; i < sourceSlice .Len (); i ++ {
497+ sourceElem := sourceSlice .Index (i )
498+ targetElem := newSlice .Index (i )
499+
500+ if elementType .Kind () == reflect .Ptr {
501+ newElem := reflect .New (elementType .Elem ())
502+ if err := setFlexibleValue (newElem .Elem (), sourceElem .Interface ()); err != nil {
503+ return err
504+ }
505+ targetElem .Set (newElem )
506+ } else {
507+ if err := setFlexibleValue (targetElem , sourceElem .Interface ()); err != nil {
508+ return err
509+ }
510+ }
511+ }
512+
513+ field .Set (newSlice )
514+ return nil
515+ }
516+
517+ // setStructValue converts struct values
518+ func setStructValue (field reflect.Value , value interface {}) error {
519+ if mapValue , ok := value .(map [string ]interface {}); ok {
520+ return flexibleMapToStruct (mapValue , field .Addr ().Interface ())
521+ }
522+ return fmt .Errorf ("cannot convert %T to struct" , value )
523+ }
524+
240525// validateConfig validates the client configuration
241526func validateConfig (config * Config ) error {
242527 if config .BaseURL == "" {
0 commit comments