github.com/moleculer-go/moleculer@v0.3.3/payload/arrayTransformers.go (about)

     1  package payload
     2  
     3  import (
     4  	"reflect"
     5  	"time"
     6  
     7  	"github.com/moleculer-go/moleculer"
     8  )
     9  
    10  type interfaceArrayFunc func(source *interface{}) []interface{}
    11  type arrayLenFunc func(source *interface{}) int
    12  type firstFunc func(source *interface{}) interface{}
    13  
    14  type arrayTransformer struct {
    15  	name           string
    16  	InterfaceArray interfaceArrayFunc
    17  	First          firstFunc
    18  	ArrayLen       arrayLenFunc
    19  }
    20  
    21  var arrayTransformers = []arrayTransformer{
    22  	arrayTransformer{
    23  		"[]interface {}",
    24  		func(source *interface{}) []interface{} {
    25  			return (*source).([]interface{})
    26  		},
    27  		func(source *interface{}) interface{} {
    28  			return (*source).([]interface{})[0]
    29  		},
    30  		func(source *interface{}) int {
    31  			return len((*source).([]interface{}))
    32  		},
    33  	},
    34  	arrayTransformer{
    35  		"[]string",
    36  		func(source *interface{}) []interface{} {
    37  			sourceList := (*source).([]string)
    38  			result := make([]interface{}, len(sourceList))
    39  			for index, value := range sourceList {
    40  				result[index] = value
    41  			}
    42  			return result
    43  		},
    44  		func(source *interface{}) interface{} {
    45  			return (*source).([]string)[0]
    46  		},
    47  		func(source *interface{}) int {
    48  			return len((*source).([]string))
    49  		},
    50  	},
    51  	arrayTransformer{
    52  		"[]int",
    53  		func(source *interface{}) []interface{} {
    54  			sourceList := (*source).([]int)
    55  			result := make([]interface{}, len(sourceList))
    56  			for index, value := range sourceList {
    57  				result[index] = value
    58  			}
    59  			return result
    60  		},
    61  		func(source *interface{}) interface{} {
    62  			return (*source).([]int)[0]
    63  		},
    64  		func(source *interface{}) int {
    65  			return len((*source).([]int))
    66  		},
    67  	},
    68  	arrayTransformer{
    69  		"[]bool",
    70  		func(source *interface{}) []interface{} {
    71  			sourceList := (*source).([]bool)
    72  			result := make([]interface{}, len(sourceList))
    73  			for index, value := range sourceList {
    74  				result[index] = value
    75  			}
    76  			return result
    77  		},
    78  		func(source *interface{}) interface{} {
    79  			return (*source).([]bool)[0]
    80  		},
    81  		func(source *interface{}) int {
    82  			return len((*source).([]bool))
    83  		},
    84  	},
    85  	arrayTransformer{
    86  		"[]int64",
    87  		func(source *interface{}) []interface{} {
    88  			sourceList := (*source).([]int64)
    89  			result := make([]interface{}, len(sourceList))
    90  			for index, value := range sourceList {
    91  				result[index] = value
    92  			}
    93  			return result
    94  		},
    95  		func(source *interface{}) interface{} {
    96  			return (*source).([]int64)[0]
    97  		},
    98  		func(source *interface{}) int {
    99  			return len((*source).([]int64))
   100  		},
   101  	},
   102  	arrayTransformer{
   103  		"[]float32",
   104  		func(source *interface{}) []interface{} {
   105  			sourceList := (*source).([]float32)
   106  			result := make([]interface{}, len(sourceList))
   107  			for index, value := range sourceList {
   108  				result[index] = value
   109  			}
   110  			return result
   111  		},
   112  		func(source *interface{}) interface{} {
   113  			return (*source).([]float32)[0]
   114  		},
   115  		func(source *interface{}) int {
   116  			return len((*source).([]float32))
   117  		},
   118  	},
   119  	arrayTransformer{
   120  		"[]float64",
   121  		func(source *interface{}) []interface{} {
   122  			sourceList := (*source).([]float64)
   123  			result := make([]interface{}, len(sourceList))
   124  			for index, value := range sourceList {
   125  				result[index] = value
   126  			}
   127  			return result
   128  		},
   129  		func(source *interface{}) interface{} {
   130  			return (*source).([]float64)[0]
   131  		},
   132  		func(source *interface{}) int {
   133  			return len((*source).([]float64))
   134  		},
   135  	},
   136  	arrayTransformer{
   137  		"[]uint64",
   138  		func(source *interface{}) []interface{} {
   139  			sourceList := (*source).([]uint64)
   140  			result := make([]interface{}, len(sourceList))
   141  			for index, value := range sourceList {
   142  				result[index] = value
   143  			}
   144  			return result
   145  		},
   146  		func(source *interface{}) interface{} {
   147  			return (*source).([]uint64)[0]
   148  		},
   149  		func(source *interface{}) int {
   150  			return len((*source).([]uint64))
   151  		},
   152  	},
   153  	arrayTransformer{
   154  		"[]time.Time",
   155  		func(source *interface{}) []interface{} {
   156  			sourceList := (*source).([]time.Time)
   157  			result := make([]interface{}, len(sourceList))
   158  			for index, value := range sourceList {
   159  				result[index] = value
   160  			}
   161  			return result
   162  		},
   163  		func(source *interface{}) interface{} {
   164  			return (*source).([]time.Time)[0]
   165  		},
   166  		func(source *interface{}) int {
   167  			return len((*source).([]time.Time))
   168  		},
   169  	},
   170  	arrayTransformer{
   171  		"[]map[string]interface {}",
   172  		func(source *interface{}) []interface{} {
   173  			sourceList := (*source).([]map[string]interface{})
   174  			result := make([]interface{}, len(sourceList))
   175  			for index, value := range sourceList {
   176  				result[index] = value
   177  			}
   178  			return result
   179  		},
   180  		func(source *interface{}) interface{} {
   181  			return (*source).([]map[string]interface{})[0]
   182  		},
   183  		func(source *interface{}) int {
   184  			return len((*source).([]map[string]interface{}))
   185  		},
   186  	},
   187  	arrayTransformer{
   188  		"[]moleculer.Payload",
   189  		func(source *interface{}) []interface{} {
   190  			sourceList := (*source).([]moleculer.Payload)
   191  			result := make([]interface{}, len(sourceList))
   192  			for index, value := range sourceList {
   193  				result[index] = value.Value()
   194  			}
   195  			return result
   196  		},
   197  		func(source *interface{}) interface{} {
   198  			return (*source).([]moleculer.Payload)[0]
   199  		},
   200  		func(source *interface{}) int {
   201  			return len((*source).([]moleculer.Payload))
   202  		},
   203  	},
   204  }
   205  
   206  func rawPayloadArrayTransformerFirst(source *interface{}) interface{} {
   207  	return (*source).(*RawPayload).First()
   208  }
   209  
   210  func rawPayloadArrayTransformer(source *interface{}) []interface{} {
   211  	sourceList := (*source).(*RawPayload)
   212  	result := make([]interface{}, sourceList.Len())
   213  	sourceList.ForEach(func(index interface{}, value moleculer.Payload) bool {
   214  		result[index.(int)] = value.Value()
   215  		return true
   216  	})
   217  	return result
   218  }
   219  
   220  func rawPayloadArrayTransformerLen(source *interface{}) int {
   221  	sourceList := (*source).(*RawPayload)
   222  	return sourceList.Len()
   223  }
   224  
   225  func reflectionArrayTransformerFirst(source *interface{}) interface{} {
   226  	rv := reflect.ValueOf(*source)
   227  	return rv.Index(0).Interface()
   228  }
   229  
   230  func reflectionArrayTransformer(source *interface{}) []interface{} {
   231  	rv := reflect.ValueOf(*source)
   232  	result := make([]interface{}, rv.Len())
   233  	for i := 0; i < rv.Len(); i++ {
   234  		item := rv.Index(i)
   235  		value := item.Interface()
   236  		if item.Kind() == reflect.Map {
   237  			mt := MapTransformer(&value)
   238  			result[i] = mt.AsMap(&value)
   239  		} else if item.Kind() == reflect.Array || item.Kind() == reflect.Slice {
   240  			at := ArrayTransformer(&value)
   241  			result[i] = at.InterfaceArray(&value)
   242  		} else {
   243  			result[i] = value
   244  		}
   245  	}
   246  	return result
   247  }
   248  
   249  func reflectionArraySize(source *interface{}) int {
   250  	rv := reflect.ValueOf(*source)
   251  	return rv.Len()
   252  }
   253  
   254  // ArrayTransformer : return the array/slice transformer for the specific map type
   255  func ArrayTransformer(value *interface{}) *arrayTransformer {
   256  	valueType := GetValueType(value)
   257  	for _, transformer := range arrayTransformers {
   258  		if valueType == transformer.name {
   259  			return &transformer
   260  		}
   261  	}
   262  	if valueType == "*payload.RawPayload" && (*value).(*RawPayload).IsArray() {
   263  		transformer := arrayTransformer{
   264  			"*payload.RawPayload",
   265  			rawPayloadArrayTransformer,
   266  			rawPayloadArrayTransformerFirst,
   267  			rawPayloadArrayTransformerLen,
   268  		}
   269  		return &transformer
   270  	}
   271  
   272  	//try to use reflection
   273  	rt := reflect.TypeOf(*value)
   274  	if rt != nil && (rt.Kind() == reflect.Array || rt.Kind() == reflect.Slice) {
   275  		return &arrayTransformer{"reflection", reflectionArrayTransformer, reflectionArrayTransformerFirst, reflectionArraySize}
   276  	}
   277  	//fmt.Println("ArrayTransformer() no transformer for  valueType -> ", valueType)
   278  	return nil
   279  }