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  }