github.com/cloudwego/hertz@v0.9.3/pkg/app/server/binding/internal/decoder/text_decoder.go (about) 1 /* 2 * Copyright 2023 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 * MIT License 16 * 17 * Copyright (c) 2019-present Fenny and Contributors 18 * 19 * Permission is hereby granted, free of charge, to any person obtaining a copy 20 * of this software and associated documentation files (the "Software"), to deal 21 * in the Software without restriction, including without limitation the rights 22 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 * copies of the Software, and to permit persons to whom the Software is 24 * furnished to do so, subject to the following conditions: 25 * 26 * The above copyright notice and this permission notice shall be included in all 27 * copies or substantial portions of the Software. 28 * 29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 * SOFTWARE. 36 * 37 * This file may have been modified by CloudWeGo authors. All CloudWeGo 38 * Modifications are Copyright 2023 CloudWeGo Authors 39 */ 40 41 package decoder 42 43 import ( 44 "fmt" 45 "reflect" 46 "strconv" 47 48 "github.com/cloudwego/hertz/internal/bytesconv" 49 hJson "github.com/cloudwego/hertz/pkg/common/json" 50 ) 51 52 type TextDecoder interface { 53 UnmarshalString(s string, fieldValue reflect.Value, looseZeroMode bool) error 54 } 55 56 func SelectTextDecoder(rt reflect.Type) (TextDecoder, error) { 57 switch rt.Kind() { 58 case reflect.Bool: 59 return &boolDecoder{}, nil 60 case reflect.Uint8: 61 return &uintDecoder{bitSize: 8}, nil 62 case reflect.Uint16: 63 return &uintDecoder{bitSize: 16}, nil 64 case reflect.Uint32: 65 return &uintDecoder{bitSize: 32}, nil 66 case reflect.Uint64: 67 return &uintDecoder{bitSize: 64}, nil 68 case reflect.Uint: 69 return &uintDecoder{}, nil 70 case reflect.Int8: 71 return &intDecoder{bitSize: 8}, nil 72 case reflect.Int16: 73 return &intDecoder{bitSize: 16}, nil 74 case reflect.Int32: 75 return &intDecoder{bitSize: 32}, nil 76 case reflect.Int64: 77 return &intDecoder{bitSize: 64}, nil 78 case reflect.Int: 79 return &intDecoder{}, nil 80 case reflect.String: 81 return &stringDecoder{}, nil 82 case reflect.Float32: 83 return &floatDecoder{bitSize: 32}, nil 84 case reflect.Float64: 85 return &floatDecoder{bitSize: 64}, nil 86 case reflect.Interface: 87 return &interfaceDecoder{}, nil 88 } 89 90 return nil, fmt.Errorf("unsupported type %s", rt.String()) 91 } 92 93 type boolDecoder struct{} 94 95 func (d *boolDecoder) UnmarshalString(s string, fieldValue reflect.Value, looseZeroMode bool) error { 96 if s == "" && looseZeroMode { 97 s = "false" 98 } 99 v, err := strconv.ParseBool(s) 100 if err != nil { 101 return err 102 } 103 fieldValue.SetBool(v) 104 return nil 105 } 106 107 type floatDecoder struct { 108 bitSize int 109 } 110 111 func (d *floatDecoder) UnmarshalString(s string, fieldValue reflect.Value, looseZeroMode bool) error { 112 if s == "" && looseZeroMode { 113 s = "0.0" 114 } 115 v, err := strconv.ParseFloat(s, d.bitSize) 116 if err != nil { 117 return err 118 } 119 fieldValue.SetFloat(v) 120 return nil 121 } 122 123 type intDecoder struct { 124 bitSize int 125 } 126 127 func (d *intDecoder) UnmarshalString(s string, fieldValue reflect.Value, looseZeroMode bool) error { 128 if s == "" && looseZeroMode { 129 s = "0" 130 } 131 v, err := strconv.ParseInt(s, 10, d.bitSize) 132 if err != nil { 133 return err 134 } 135 fieldValue.SetInt(v) 136 return nil 137 } 138 139 type stringDecoder struct{} 140 141 func (d *stringDecoder) UnmarshalString(s string, fieldValue reflect.Value, looseZeroMode bool) error { 142 fieldValue.SetString(s) 143 return nil 144 } 145 146 type uintDecoder struct { 147 bitSize int 148 } 149 150 func (d *uintDecoder) UnmarshalString(s string, fieldValue reflect.Value, looseZeroMode bool) error { 151 if s == "" && looseZeroMode { 152 s = "0" 153 } 154 v, err := strconv.ParseUint(s, 10, d.bitSize) 155 if err != nil { 156 return err 157 } 158 fieldValue.SetUint(v) 159 return nil 160 } 161 162 type interfaceDecoder struct{} 163 164 func (d *interfaceDecoder) UnmarshalString(s string, fieldValue reflect.Value, looseZeroMode bool) error { 165 if s == "" && looseZeroMode { 166 s = "0" 167 } 168 return hJson.Unmarshal(bytesconv.S2b(s), fieldValue.Addr().Interface()) 169 }