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 }