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  }