github.com/cloudwego/kitex@v0.9.0/pkg/generic/descriptor/value_mapping.go (about) 1 /* 2 * Copyright 2021 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package descriptor 18 19 import ( 20 "context" 21 "strconv" 22 ) 23 24 // ValueMapping value mapping annotation 25 type ValueMapping interface { 26 Request(ctx context.Context, val interface{}, field *FieldDescriptor) (interface{}, error) 27 Response(ctx context.Context, val interface{}, field *FieldDescriptor) (interface{}, error) 28 } 29 30 // NewValueMapping ValueMapping creator 31 type NewValueMapping func(value string) ValueMapping 32 33 // APIJSConvAnnotation api.js_conv annotation 34 var APIJSConvAnnotation = NewBAMAnnotation("api.js_conv", NewAPIJSConv) 35 36 type apiJSConv struct{} 37 38 // NewAPIJSConv ... 39 var NewAPIJSConv NewValueMapping = func(value string) ValueMapping { 40 // ignore the value 41 return &apiJSConv{} 42 } 43 44 // FIXME: compatible with old usages 45 // we just return the origin val instead of return error 46 func (m *apiJSConv) Request(ctx context.Context, val interface{}, field *FieldDescriptor) (interface{}, error) { 47 switch v := val.(type) { 48 case string: 49 i, _ := strconv.ParseInt(v, 10, 64) 50 return i, nil 51 case []interface{}: 52 res := make([]interface{}, 0, len(v)) 53 for _, s := range v { 54 if str, ok := s.(string); ok { 55 i, _ := strconv.ParseInt(str, 10, 64) 56 res = append(res, i) 57 } else { 58 return val, nil 59 } 60 } 61 return res, nil 62 case map[interface{}]interface{}: 63 nv := make(map[interface{}]interface{}, len(v)) 64 for key, value := range v { 65 nvalue, err := m.Request(ctx, value, field) 66 if err != nil { 67 return nil, err 68 } 69 nv[key] = nvalue 70 } 71 return nv, nil 72 case map[string]interface{}: 73 nv := make(map[string]interface{}, len(v)) 74 for key, value := range v { 75 nvalue, err := m.Request(ctx, value, field) 76 if err != nil { 77 return nil, err 78 } 79 nv[key] = nvalue 80 } 81 return nv, nil 82 } 83 return val, nil 84 } 85 86 func (m *apiJSConv) Response(ctx context.Context, val interface{}, field *FieldDescriptor) (interface{}, error) { 87 switch v := val.(type) { 88 case int64: 89 return strconv.FormatInt(v, 10), nil 90 case []interface{}: 91 res := make([]interface{}, 0, len(v)) 92 for _, i := range v { 93 if i64, ok := i.(int64); ok { 94 res = append(res, strconv.FormatInt(i64, 10)) 95 } else { 96 return val, nil 97 } 98 } 99 return res, nil 100 case map[interface{}]interface{}: 101 nv := make(map[interface{}]interface{}, len(v)) 102 for key, value := range v { 103 nvalue, err := m.Response(ctx, value, field) 104 if err != nil { 105 return nil, err 106 } 107 nv[key] = nvalue 108 } 109 return nv, nil 110 case map[string]interface{}: 111 nv := make(map[string]interface{}, len(v)) 112 for key, value := range v { 113 nvalue, err := m.Response(ctx, value, field) 114 if err != nil { 115 return nil, err 116 } 117 nv[key] = nvalue 118 } 119 return nv, nil 120 } 121 return val, nil 122 }