github.com/cloudwego/kitex@v0.9.0/pkg/generic/thrift/util.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 thrift 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "strconv" 24 "strings" 25 26 "github.com/cloudwego/kitex/pkg/generic/descriptor" 27 ) 28 29 func assertType(expected, but descriptor.Type) error { 30 if expected == but { 31 return nil 32 } 33 return fmt.Errorf("need %s type, but got: %s", expected, but) 34 } 35 36 func splitType(t string) (pkg, name string) { 37 idx := strings.LastIndex(t, ".") 38 if idx == -1 { 39 return "", t 40 } 41 return t[:idx], t[idx+1:] 42 } 43 44 func requestMappingValue(ctx context.Context, req *descriptor.HTTPRequest, field *descriptor.FieldDescriptor) (interface{}, error) { 45 val, ok, err := field.HTTPMapping.Request(ctx, req, field) 46 if err != nil { 47 return nil, err 48 } 49 if !ok { 50 return nil, nil 51 } 52 t := field.Type 53 switch v := val.(type) { 54 case json.Number: 55 bt, err := buildinTypeFromString(string(v), t) 56 if err != nil { 57 return v, nil 58 } 59 return bt, nil 60 case string: 61 bt, err := buildinTypeFromString(v, t) 62 if err != nil { 63 return v, nil 64 } 65 return bt, err 66 } 67 return val, nil 68 } 69 70 func buildinTypeFromString(s string, t *descriptor.TypeDescriptor) (interface{}, error) { 71 tt := t.Type 72 switch tt { 73 case descriptor.BOOL: 74 switch s { 75 case "true": 76 return true, nil 77 case "false": 78 return false, nil 79 } 80 case descriptor.I08: 81 i, err := strconv.ParseInt(s, 10, 8) 82 if err != nil { 83 return nil, err 84 } 85 return int8(i), nil 86 case descriptor.I16: 87 i, err := strconv.ParseInt(s, 10, 16) 88 if err != nil { 89 return nil, err 90 } 91 return int16(i), nil 92 case descriptor.I32: 93 i, err := strconv.ParseInt(s, 10, 32) 94 if err != nil { 95 return nil, err 96 } 97 return int32(i), nil 98 case descriptor.I64: 99 i, err := strconv.ParseInt(s, 10, 64) 100 if err != nil { 101 return nil, err 102 } 103 return i, nil 104 case descriptor.DOUBLE: 105 return strconv.ParseFloat(s, 64) 106 case descriptor.STRING: 107 return s, nil 108 case descriptor.LIST: 109 strs := strings.Split(s, ",") 110 if len(strs) == 0 { 111 return nil, fmt.Errorf("expected list, got:%s", s) 112 } 113 res := make([]interface{}, len(strs)) 114 for i, str := range strs { 115 val, err := buildinTypeFromString(str, t.Elem) 116 if err != nil { 117 return nil, err 118 } 119 res[i] = val 120 } 121 return res, nil 122 } 123 return nil, fmt.Errorf("unsupported type:%s for parse buildin types from string", tt) 124 } 125 126 func buildinTypeIntoString(val interface{}) string { 127 switch v := val.(type) { 128 case bool: 129 return strconv.FormatBool(v) 130 case int8: 131 return strconv.FormatInt(int64(v), 10) 132 case int16: 133 return strconv.FormatInt(int64(v), 10) 134 case int32: 135 return strconv.FormatInt(int64(v), 10) 136 case int64: 137 return strconv.FormatInt(v, 10) 138 case float64: 139 return strconv.FormatFloat(v, 'f', -1, 64) 140 case string: 141 return v 142 } 143 return "" 144 }