// createMapResponse is a helper for generating a response value from // a value of type map. func createMapResponse(value reflect.Value, options objx.Map, constructor func(interface{}, interface{}) interface{}, domain string) interface{} { response := reflect.MakeMap(value.Type()) for _, key := range value.MapKeys() { var elementOptions objx.Map keyStr := key.Interface().(string) if options != nil { var elementOptionsValue *objx.Value if options.Has(keyStr) { elementOptionsValue = options.Get(keyStr) } else if options.Has("*") { elementOptionsValue = options.Get("*") } if elementOptionsValue.IsMSI() { elementOptions = objx.Map(elementOptionsValue.MSI()) } else if elementOptionsValue.IsObjxMap() { elementOptions = elementOptionsValue.ObjxMap() } else { panic("Don't know what to do with option") } } itemResponse := createResponseValue(value.MapIndex(key), elementOptions, constructor, domain) response.SetMapIndex(key, reflect.ValueOf(itemResponse)) } return response.Interface() }
// createStructResponse is a helper for generating a response value // from a value of type struct. func createStructResponse(value reflect.Value, options objx.Map, constructor func(interface{}, interface{}) interface{}, domain string) interface{} { structType := value.Type() // Support "database/sql".Null* types, and any other types // matching that structure if v, err := createNullableDbResponse(value, structType); err == nil { return v } response := make(objx.Map) for i := 0; i < value.NumField(); i++ { fieldType := structType.Field(i) fieldValue := value.Field(i) if fieldType.Anonymous { embeddedResponse := CreateResponse(fieldValue.Interface(), options, constructor, domain).(objx.Map) for key, value := range embeddedResponse { // Don't overwrite values from the base struct if _, ok := response[key]; !ok { response[key] = value } } } else if unicode.IsUpper(rune(fieldType.Name[0])) { name := ResponseTag(fieldType) switch name { case "-": continue default: var subOptions objx.Map if options != nil && (options.Has(name) || options.Has("*")) { var subOptionsValue *objx.Value if options.Has(name) { subOptionsValue = options.Get(name) } else { subOptionsValue = options.Get("*") } if subOptionsValue.IsMSI() { subOptions = objx.Map(subOptionsValue.MSI()) } else if subOptionsValue.IsObjxMap() { subOptions = subOptionsValue.ObjxMap() } else { panic("Don't know what to do with option") } } response[name] = createResponseValue(fieldValue, subOptions, constructor, domain) } } } return response }