package bunqapi import ( "fmt" "reflect" ) // MergeStructs merges an array of structs into a single struct. func MergeStructs(responses interface{}, mergedResp interface{}) { arrayType := reflect.TypeOf(responses) if arrayType.Kind() != reflect.Slice && arrayType.Kind() != reflect.Array { panic(fmt.Sprintf("responses should be a slice or array, not %v", arrayType.Kind())) } responsesValue := reflect.ValueOf(responses) numResponses := responsesValue.Len() respType := arrayType.Elem() numFields := respType.NumField() resultType := reflect.TypeOf(mergedResp) if resultType.Elem() != respType { panic(fmt.Sprintf("mergedResp should be *%v, not %v", respType, reflect.TypeOf(mergedResp))) } resultValue := reflect.ValueOf(mergedResp).Elem() for index := 0; index < numResponses; index++ { // fmt.Printf("response #%d:\n", index) responseValue := responsesValue.Index(index) for fieldnum := 0; fieldnum < numFields; fieldnum++ { // field := respType.Field(fieldnum) fieldVal := responseValue.Field(fieldnum) // Skip unexported fields. if !fieldVal.CanSet() { continue } // fmt.Printf(" - field %d: %10v ", fieldnum, field.Name) useValue := false switch fieldVal.Kind() { case reflect.Ptr: useValue = !fieldVal.IsNil() // fmt.Printf("is pointer: %v", useValue) case reflect.String: useValue = fieldVal.String() != "" // fmt.Printf("is string : %v", useValue) case reflect.Bool: useValue = fieldVal.Bool() // fmt.Printf("is bool : %v", useValue) default: // fmt.Printf("is kind : %v (not using)", fieldVal.Kind()) } // fmt.Println() if !useValue { continue } resultField := resultValue.Field(fieldnum) resultField.Set(fieldVal) } } }