github.com/angryronald/go-kit@v0.0.0-20240505173814-ff2bd9c79dbf/cast/object.transformer.go (about) 1 package cast 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "reflect" 7 "time" 8 9 "github.com/google/uuid" 10 "github.com/sirupsen/logrus" 11 ) 12 13 // TransformObject used to transform source object to result object based on json tag 14 func TransformObject(source interface{}, result interface{}) error { 15 sourceBytes, err := json.Marshal(source) 16 if err != nil { 17 return err 18 } 19 20 err = json.Unmarshal(sourceBytes, &result) 21 if err != nil { 22 return err 23 } 24 25 return nil 26 } 27 28 func FromBytes(source []byte, result interface{}) error { 29 return json.Unmarshal(source, result) 30 } 31 32 func ToBytes(source interface{}) ([]byte, error) { 33 return json.Marshal(source) 34 } 35 36 func InterfacePointerArrayToInterfaceArray(source []*interface{}) []interface{} { 37 var result []interface{} 38 for _, o := range source { 39 result = append(result, *o) 40 } 41 42 return result 43 } 44 45 func StructPointerArrayToInterfaceArray(source interface{}) []interface{} { 46 s := reflect.ValueOf(source) 47 if s.Kind() != reflect.Slice { 48 logrus.Fatal("StructPointerArrayToInterfaceArray called with a non-slice value") 49 } 50 51 result := make([]interface{}, s.Len()) 52 53 for i := 0; i < s.Len(); i++ { 54 // if s.Index(i).Kind() != reflect.Ptr { 55 // logrus.Fatal("PointerArrayStructToInterfaceArray called with a slice of non pointer") 56 // } 57 result[i] = s.Index(i).Elem().Interface() 58 } 59 60 return result 61 } 62 63 func StructPointerArrayToInterfacePointerArray(source interface{}) []interface{} { 64 s := reflect.ValueOf(source) 65 if s.Kind() != reflect.Slice { 66 logrus.Fatal("StructPointerArrayToInterfacePointerArray called with a non-slice value") 67 } 68 69 result := make([]interface{}, s.Len()) 70 71 for i := 0; i < s.Len(); i++ { 72 result[i] = s.Index(i).Interface() 73 } 74 75 return result 76 } 77 78 func InterfaceArrayToPointerArray(slice interface{}) interface{} { 79 sliceValue := reflect.ValueOf(slice) 80 if sliceValue.Kind() != reflect.Slice { 81 logrus.Fatal("InterfaceArrayToPointerArray called with a non-slice value") 82 } 83 84 elemType := sliceValue.Type().Elem() 85 pointerType := reflect.PtrTo(elemType) 86 87 result := reflect.MakeSlice(reflect.SliceOf(pointerType), sliceValue.Len(), sliceValue.Len()) 88 89 for i := 0; i < sliceValue.Len(); i++ { 90 elem := sliceValue.Index(i) 91 pointer := reflect.New(elemType).Elem() 92 pointer.Set(elem) 93 result.Index(i).Set(pointer.Addr()) 94 } 95 96 return result.Interface() 97 } 98 99 func ToPointerObject(obj interface{}) interface{} { 100 objType := reflect.TypeOf(obj) 101 // ptrType := reflect.PtrTo(objType) 102 ptr := reflect.New(objType).Elem() 103 ptr.Set(reflect.ValueOf(obj)) 104 return ptr.Addr().Interface() 105 } 106 107 // ObjectToStructPointerSlice takes a struct object as input and returns a slice of struct pointers. 108 func ObjectToStructPointerSlice(obj interface{}) interface{} { 109 objType := reflect.TypeOf(obj) 110 if objType.Kind() != reflect.Struct && objType.Kind() != reflect.Pointer { 111 panic("Input is not a struct") 112 } 113 114 // Create a slice type with elements being pointers to the struct type. 115 var sliceType reflect.Type 116 if objType.Kind() == reflect.Struct { 117 sliceType = reflect.SliceOf(reflect.PtrTo(objType)) 118 } 119 if objType.Kind() == reflect.Pointer { 120 sliceType = reflect.SliceOf(objType) 121 } 122 123 // Create a new slice with the desired type. 124 newSlice := reflect.MakeSlice(sliceType, 1, 1) 125 126 // Set the pointer value in the slice. 127 if objType.Kind() == reflect.Struct { 128 newSlice.Index(0).Set(reflect.ValueOf(ToPointerObject(obj))) 129 } 130 if objType.Kind() == reflect.Pointer { 131 newSlice.Index(0).Set(reflect.ValueOf(obj)) 132 } 133 // Return the new slice as an interface. 134 return newSlice.Interface() 135 } 136 137 func ToString(value interface{}) (string, error) { 138 // Use reflection to handle different data types. 139 switch v := value.(type) { 140 case string: 141 return v, nil 142 case int: 143 return fmt.Sprintf("%d", v), nil 144 case int64: 145 return fmt.Sprintf("%d", v), nil 146 case float64: 147 return fmt.Sprintf("%f", v), nil 148 case time.Time: 149 return v.String(), nil 150 case uuid.UUID: 151 return v.String(), nil 152 default: 153 return fmt.Sprint(value), nil 154 } 155 }