123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- package param
- import (
- "encoding/json"
- "reflect"
- "strconv"
- "strings"
- "time"
- )
- type paramParser interface {
- parse(value string, toType reflect.Type) (interface{}, error)
- }
- func getParser(param *MethodParam, t reflect.Type) paramParser {
- switch t.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return intParser{}
- case reflect.Slice:
- if t.Elem().Kind() == reflect.Uint8 { //treat []byte as string
- return stringParser{}
- }
- if param.in == body {
- return jsonParser{}
- }
- elemParser := getParser(param, t.Elem())
- if elemParser == (jsonParser{}) {
- return elemParser
- }
- return sliceParser(elemParser)
- case reflect.Bool:
- return boolParser{}
- case reflect.String:
- return stringParser{}
- case reflect.Float32, reflect.Float64:
- return floatParser{}
- case reflect.Ptr:
- elemParser := getParser(param, t.Elem())
- if elemParser == (jsonParser{}) {
- return elemParser
- }
- return ptrParser(elemParser)
- default:
- if t.PkgPath() == "time" && t.Name() == "Time" {
- return timeParser{}
- }
- return jsonParser{}
- }
- }
- type parserFunc func(value string, toType reflect.Type) (interface{}, error)
- func (f parserFunc) parse(value string, toType reflect.Type) (interface{}, error) {
- return f(value, toType)
- }
- type boolParser struct {
- }
- func (p boolParser) parse(value string, toType reflect.Type) (interface{}, error) {
- return strconv.ParseBool(value)
- }
- type stringParser struct {
- }
- func (p stringParser) parse(value string, toType reflect.Type) (interface{}, error) {
- return value, nil
- }
- type intParser struct {
- }
- func (p intParser) parse(value string, toType reflect.Type) (interface{}, error) {
- return strconv.Atoi(value)
- }
- type floatParser struct {
- }
- func (p floatParser) parse(value string, toType reflect.Type) (interface{}, error) {
- if toType.Kind() == reflect.Float32 {
- res, err := strconv.ParseFloat(value, 32)
- if err != nil {
- return nil, err
- }
- return float32(res), nil
- }
- return strconv.ParseFloat(value, 64)
- }
- type timeParser struct {
- }
- func (p timeParser) parse(value string, toType reflect.Type) (result interface{}, err error) {
- result, err = time.Parse(time.RFC3339, value)
- if err != nil {
- result, err = time.Parse("2006-01-02", value)
- }
- return
- }
- type jsonParser struct {
- }
- func (p jsonParser) parse(value string, toType reflect.Type) (interface{}, error) {
- pResult := reflect.New(toType)
- v := pResult.Interface()
- err := json.Unmarshal([]byte(value), v)
- if err != nil {
- return nil, err
- }
- return pResult.Elem().Interface(), nil
- }
- func sliceParser(elemParser paramParser) paramParser {
- return parserFunc(func(value string, toType reflect.Type) (interface{}, error) {
- values := strings.Split(value, ",")
- result := reflect.MakeSlice(toType, 0, len(values))
- elemType := toType.Elem()
- for _, v := range values {
- parsedValue, err := elemParser.parse(v, elemType)
- if err != nil {
- return nil, err
- }
- result = reflect.Append(result, reflect.ValueOf(parsedValue))
- }
- return result.Interface(), nil
- })
- }
- func ptrParser(elemParser paramParser) paramParser {
- return parserFunc(func(value string, toType reflect.Type) (interface{}, error) {
- parsedValue, err := elemParser.parse(value, toType.Elem())
- if err != nil {
- return nil, err
- }
- newValPtr := reflect.New(toType.Elem())
- newVal := reflect.Indirect(newValPtr)
- convertedVal, err := safeConvert(reflect.ValueOf(parsedValue), toType.Elem())
- if err != nil {
- return nil, err
- }
- newVal.Set(convertedVal)
- return newValPtr.Interface(), nil
- })
- }
|