github.com/astaxie/beego@v1.12.3/context/param/parsers.go (about)

     1  package param
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  	"strconv"
     7  	"strings"
     8  	"time"
     9  )
    10  
    11  type paramParser interface {
    12  	parse(value string, toType reflect.Type) (interface{}, error)
    13  }
    14  
    15  func getParser(param *MethodParam, t reflect.Type) paramParser {
    16  	switch t.Kind() {
    17  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
    18  		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    19  		return intParser{}
    20  	case reflect.Slice:
    21  		if t.Elem().Kind() == reflect.Uint8 { //treat []byte as string
    22  			return stringParser{}
    23  		}
    24  		if param.in == body {
    25  			return jsonParser{}
    26  		}
    27  		elemParser := getParser(param, t.Elem())
    28  		if elemParser == (jsonParser{}) {
    29  			return elemParser
    30  		}
    31  		return sliceParser(elemParser)
    32  	case reflect.Bool:
    33  		return boolParser{}
    34  	case reflect.String:
    35  		return stringParser{}
    36  	case reflect.Float32, reflect.Float64:
    37  		return floatParser{}
    38  	case reflect.Ptr:
    39  		elemParser := getParser(param, t.Elem())
    40  		if elemParser == (jsonParser{}) {
    41  			return elemParser
    42  		}
    43  		return ptrParser(elemParser)
    44  	default:
    45  		if t.PkgPath() == "time" && t.Name() == "Time" {
    46  			return timeParser{}
    47  		}
    48  		return jsonParser{}
    49  	}
    50  }
    51  
    52  type parserFunc func(value string, toType reflect.Type) (interface{}, error)
    53  
    54  func (f parserFunc) parse(value string, toType reflect.Type) (interface{}, error) {
    55  	return f(value, toType)
    56  }
    57  
    58  type boolParser struct {
    59  }
    60  
    61  func (p boolParser) parse(value string, toType reflect.Type) (interface{}, error) {
    62  	return strconv.ParseBool(value)
    63  }
    64  
    65  type stringParser struct {
    66  }
    67  
    68  func (p stringParser) parse(value string, toType reflect.Type) (interface{}, error) {
    69  	return value, nil
    70  }
    71  
    72  type intParser struct {
    73  }
    74  
    75  func (p intParser) parse(value string, toType reflect.Type) (interface{}, error) {
    76  	return strconv.Atoi(value)
    77  }
    78  
    79  type floatParser struct {
    80  }
    81  
    82  func (p floatParser) parse(value string, toType reflect.Type) (interface{}, error) {
    83  	if toType.Kind() == reflect.Float32 {
    84  		res, err := strconv.ParseFloat(value, 32)
    85  		if err != nil {
    86  			return nil, err
    87  		}
    88  		return float32(res), nil
    89  	}
    90  	return strconv.ParseFloat(value, 64)
    91  }
    92  
    93  type timeParser struct {
    94  }
    95  
    96  func (p timeParser) parse(value string, toType reflect.Type) (result interface{}, err error) {
    97  	result, err = time.Parse(time.RFC3339, value)
    98  	if err != nil {
    99  		result, err = time.Parse("2006-01-02", value)
   100  	}
   101  	return
   102  }
   103  
   104  type jsonParser struct {
   105  }
   106  
   107  func (p jsonParser) parse(value string, toType reflect.Type) (interface{}, error) {
   108  	pResult := reflect.New(toType)
   109  	v := pResult.Interface()
   110  	err := json.Unmarshal([]byte(value), v)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  	return pResult.Elem().Interface(), nil
   115  }
   116  
   117  func sliceParser(elemParser paramParser) paramParser {
   118  	return parserFunc(func(value string, toType reflect.Type) (interface{}, error) {
   119  		values := strings.Split(value, ",")
   120  		result := reflect.MakeSlice(toType, 0, len(values))
   121  		elemType := toType.Elem()
   122  		for _, v := range values {
   123  			parsedValue, err := elemParser.parse(v, elemType)
   124  			if err != nil {
   125  				return nil, err
   126  			}
   127  			result = reflect.Append(result, reflect.ValueOf(parsedValue))
   128  		}
   129  		return result.Interface(), nil
   130  	})
   131  }
   132  
   133  func ptrParser(elemParser paramParser) paramParser {
   134  	return parserFunc(func(value string, toType reflect.Type) (interface{}, error) {
   135  		parsedValue, err := elemParser.parse(value, toType.Elem())
   136  		if err != nil {
   137  			return nil, err
   138  		}
   139  		newValPtr := reflect.New(toType.Elem())
   140  		newVal := reflect.Indirect(newValPtr)
   141  		convertedVal, err := safeConvert(reflect.ValueOf(parsedValue), toType.Elem())
   142  		if err != nil {
   143  			return nil, err
   144  		}
   145  
   146  		newVal.Set(convertedVal)
   147  		return newValPtr.Interface(), nil
   148  	})
   149  }