github.com/cloudwego/hertz@v0.9.3/pkg/app/server/binding/internal/decoder/util.go (about) 1 /* 2 * Copyright 2024 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 decoder 18 19 import ( 20 "fmt" 21 "reflect" 22 "strings" 23 24 "github.com/cloudwego/hertz/internal/bytesconv" 25 hJson "github.com/cloudwego/hertz/pkg/common/json" 26 "github.com/cloudwego/hertz/pkg/protocol" 27 "github.com/cloudwego/hertz/pkg/route/param" 28 ) 29 30 const ( 31 specialChar = "\x07" 32 ) 33 34 // toDefaultValue will preprocess the default value and transfer it to be standard format 35 func toDefaultValue(typ reflect.Type, defaultValue string) string { 36 switch typ.Kind() { 37 case reflect.Slice, reflect.Array, reflect.Map, reflect.Struct: 38 // escape single quote and double quote, replace single quote with double quote 39 defaultValue = strings.Replace(defaultValue, `"`, `\"`, -1) 40 defaultValue = strings.Replace(defaultValue, `\'`, specialChar, -1) 41 defaultValue = strings.Replace(defaultValue, `'`, `"`, -1) 42 defaultValue = strings.Replace(defaultValue, specialChar, `'`, -1) 43 } 44 return defaultValue 45 } 46 47 // stringToValue is used to dynamically create reflect.Value for 'text' 48 func stringToValue(elemType reflect.Type, text string, req *protocol.Request, params param.Params, config *DecodeConfig) (v reflect.Value, err error) { 49 v = reflect.New(elemType).Elem() 50 if customizedFunc, exist := config.TypeUnmarshalFuncs[elemType]; exist { 51 val, err := customizedFunc(req, params, text) 52 if err != nil { 53 return reflect.Value{}, err 54 } 55 return val, nil 56 } 57 switch elemType.Kind() { 58 case reflect.Struct: 59 err = hJson.Unmarshal(bytesconv.S2b(text), v.Addr().Interface()) 60 case reflect.Map: 61 err = hJson.Unmarshal(bytesconv.S2b(text), v.Addr().Interface()) 62 case reflect.Array, reflect.Slice: 63 // do nothing 64 default: 65 decoder, err := SelectTextDecoder(elemType) 66 if err != nil { 67 return reflect.Value{}, fmt.Errorf("unsupported type %s for slice/array", elemType.String()) 68 } 69 err = decoder.UnmarshalString(text, v, config.LooseZeroMode) 70 if err != nil { 71 return reflect.Value{}, fmt.Errorf("unable to decode '%s' as %s: %w", text, elemType.String(), err) 72 } 73 } 74 75 return v, err 76 }