|
|
@@ -1,445 +0,0 @@
|
|
|
-package jsoniter
|
|
|
-
|
|
|
-import (
|
|
|
- "fmt"
|
|
|
- "reflect"
|
|
|
- "strconv"
|
|
|
-)
|
|
|
-
|
|
|
-// Any API is for maximum flexibility
|
|
|
-type Any struct {
|
|
|
- val interface{}
|
|
|
- Error error
|
|
|
- LastAccessed interface{}
|
|
|
-}
|
|
|
-
|
|
|
-// MakeAny creates Any instance
|
|
|
-func MakeAny(val interface{}) *Any {
|
|
|
- return &Any{val, nil, nil}
|
|
|
-}
|
|
|
-
|
|
|
-// Get extracts a json object from Any
|
|
|
-func (any *Any) Get(keys ...interface{}) interface{} {
|
|
|
- ret, err := getPath(any.val, keys...)
|
|
|
- any.LastAccessed = ret
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return ""
|
|
|
- }
|
|
|
- return ret
|
|
|
-}
|
|
|
-
|
|
|
-// GetValueType gets type of a value
|
|
|
-func (any *Any) GetValueType(keys ...interface{}) ValueType {
|
|
|
- ret, err := getPath(any.val, keys...)
|
|
|
- any.LastAccessed = ret
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return Invalid
|
|
|
- }
|
|
|
-
|
|
|
- switch reflect.TypeOf(ret).Kind() {
|
|
|
- case reflect.Uint8:
|
|
|
- return Number
|
|
|
- case reflect.Int8:
|
|
|
- return Number
|
|
|
- case reflect.Uint16:
|
|
|
- return Number
|
|
|
- case reflect.Int16:
|
|
|
- return Number
|
|
|
- case reflect.Uint32:
|
|
|
- return Number
|
|
|
- case reflect.Int32:
|
|
|
- return Number
|
|
|
- case reflect.Uint64:
|
|
|
- return Number
|
|
|
- case reflect.Int64:
|
|
|
- return Number
|
|
|
- case reflect.Int:
|
|
|
- return Number
|
|
|
- case reflect.Uint:
|
|
|
- return Number
|
|
|
- case reflect.Float32:
|
|
|
- return Number
|
|
|
- case reflect.Float64:
|
|
|
- return Number
|
|
|
- case reflect.String:
|
|
|
- return String
|
|
|
- case reflect.Bool:
|
|
|
- return Bool
|
|
|
- case reflect.Array:
|
|
|
- return Array
|
|
|
- case reflect.Struct:
|
|
|
- return Object
|
|
|
- default:
|
|
|
- return Invalid
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// ToString converts a json object to string
|
|
|
-func (any *Any) ToString(keys ...interface{}) string {
|
|
|
- ret, err := getPath(any.val, keys...)
|
|
|
- any.LastAccessed = ret
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return ""
|
|
|
- }
|
|
|
- switch ret := ret.(type) {
|
|
|
- case uint8:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case int8:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case uint16:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case int16:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case uint32:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case int32:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case uint64:
|
|
|
- return strconv.FormatUint(uint64(ret), 10)
|
|
|
- case int64:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case int:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case uint:
|
|
|
- return strconv.FormatInt(int64(ret), 10)
|
|
|
- case float32:
|
|
|
- return strconv.FormatFloat(float64(ret), 'E', -1, 32)
|
|
|
- case float64:
|
|
|
- return strconv.FormatFloat(ret, 'E', -1, 64)
|
|
|
- case string:
|
|
|
- return ret
|
|
|
- default:
|
|
|
- return fmt.Sprintf("%v", ret)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// ToUint8 converts a json object to Uint8
|
|
|
-func (any *Any) ToUint8(keys ...interface{}) uint8 {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return uint8(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToInt8 converts a json object to Int8
|
|
|
-func (any *Any) ToInt8(keys ...interface{}) int8 {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return int8(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToUint16 converts a json object to Uint16
|
|
|
-func (any *Any) ToUint16(keys ...interface{}) uint16 {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return uint16(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToInt16 converts a json object to Int16
|
|
|
-func (any *Any) ToInt16(keys ...interface{}) int16 {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return int16(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToUint32 converts a json object to Uint32
|
|
|
-func (any *Any) ToUint32(keys ...interface{}) uint32 {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return uint32(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToInt32 converts a json object to Int32
|
|
|
-func (any *Any) ToInt32(keys ...interface{}) int32 {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return int32(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToUint64 converts a json object to Uint64
|
|
|
-func (any *Any) ToUint64(keys ...interface{}) uint64 {
|
|
|
- ret, err := getPathAsUint64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return uint64(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToInt64 converts a json object to Int64
|
|
|
-func (any *Any) ToInt64(keys ...interface{}) int64 {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return int64(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToInt converts a json object to Int
|
|
|
-func (any *Any) ToInt(keys ...interface{}) int {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return int(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToUint converts a json object to Uint
|
|
|
-func (any *Any) ToUint(keys ...interface{}) uint {
|
|
|
- ret, err := getPathAsInt64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return uint(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToFloat32 converts a json object to Float32
|
|
|
-func (any *Any) ToFloat32(keys ...interface{}) float32 {
|
|
|
- ret, err := getPathAsFloat64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return float32(ret)
|
|
|
-}
|
|
|
-
|
|
|
-// ToFloat64 converts a json object to Float64
|
|
|
-func (any *Any) ToFloat64(keys ...interface{}) float64 {
|
|
|
- ret, err := getPathAsFloat64(any, keys...)
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0
|
|
|
- }
|
|
|
- return ret
|
|
|
-}
|
|
|
-
|
|
|
-// ToBool converts a json object to Bool
|
|
|
-func (any *Any) ToBool(keys ...interface{}) bool {
|
|
|
- ret, err := getPath(any.val, keys...)
|
|
|
- any.LastAccessed = ret
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return false
|
|
|
- }
|
|
|
- typedRet, ok := ret.(bool)
|
|
|
- if !ok {
|
|
|
- any.Error = fmt.Errorf("%v is not bool", ret)
|
|
|
- return false
|
|
|
- }
|
|
|
- return typedRet
|
|
|
-}
|
|
|
-
|
|
|
-// IsNil judges whether a json object is nil
|
|
|
-func (any *Any) IsNil(keys ...interface{}) bool {
|
|
|
- ret, err := getPath(any.val, keys...)
|
|
|
- any.LastAccessed = ret
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return false
|
|
|
- }
|
|
|
- return reflect.ValueOf(ret).IsNil()
|
|
|
-}
|
|
|
-
|
|
|
-func getPathAsInt64(any *Any, keys ...interface{}) (int64, error) {
|
|
|
- ret, err := getPath(any.val, keys...)
|
|
|
- any.LastAccessed = ret
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- switch ret := ret.(type) {
|
|
|
- case uint8:
|
|
|
- return int64(ret), nil
|
|
|
- case int8:
|
|
|
- return int64(ret), nil
|
|
|
- case uint16:
|
|
|
- return int64(ret), nil
|
|
|
- case int16:
|
|
|
- return int64(ret), nil
|
|
|
- case uint32:
|
|
|
- return int64(ret), nil
|
|
|
- case int32:
|
|
|
- return int64(ret), nil
|
|
|
- case uint64:
|
|
|
- return int64(ret), nil
|
|
|
- case int64:
|
|
|
- return int64(ret), nil
|
|
|
- case int:
|
|
|
- return int64(ret), nil
|
|
|
- case uint:
|
|
|
- return int64(ret), nil
|
|
|
- case float32:
|
|
|
- return int64(ret), nil
|
|
|
- case float64:
|
|
|
- return int64(ret), nil
|
|
|
- case string:
|
|
|
- intVal, err := strconv.ParseInt(ret, 10, 64)
|
|
|
- if err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- return intVal, nil
|
|
|
- default:
|
|
|
- return 0, fmt.Errorf("%v is not number", ret)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func getPathAsUint64(any *Any, keys ...interface{}) (uint64, error) {
|
|
|
- ret, err := getPath(any.val, keys...)
|
|
|
- any.LastAccessed = ret
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- switch ret := ret.(type) {
|
|
|
- case uint8:
|
|
|
- return uint64(ret), nil
|
|
|
- case int8:
|
|
|
- return uint64(ret), nil
|
|
|
- case uint16:
|
|
|
- return uint64(ret), nil
|
|
|
- case int16:
|
|
|
- return uint64(ret), nil
|
|
|
- case uint32:
|
|
|
- return uint64(ret), nil
|
|
|
- case int32:
|
|
|
- return uint64(ret), nil
|
|
|
- case uint64:
|
|
|
- return uint64(ret), nil
|
|
|
- case int64:
|
|
|
- return uint64(ret), nil
|
|
|
- case int:
|
|
|
- return uint64(ret), nil
|
|
|
- case uint:
|
|
|
- return uint64(ret), nil
|
|
|
- case float32:
|
|
|
- return uint64(ret), nil
|
|
|
- case float64:
|
|
|
- return uint64(ret), nil
|
|
|
- case string:
|
|
|
- intVal, err := strconv.ParseUint(ret, 10, 64)
|
|
|
- if err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- return intVal, nil
|
|
|
- default:
|
|
|
- return 0, fmt.Errorf("%v is not number", ret)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func getPathAsFloat64(any *Any, keys ...interface{}) (float64, error) {
|
|
|
- ret, err := getPath(any.val, keys...)
|
|
|
- any.LastAccessed = ret
|
|
|
- if err != nil {
|
|
|
- any.Error = err
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- switch ret := ret.(type) {
|
|
|
- case uint8:
|
|
|
- return float64(ret), nil
|
|
|
- case int8:
|
|
|
- return float64(ret), nil
|
|
|
- case uint16:
|
|
|
- return float64(ret), nil
|
|
|
- case int16:
|
|
|
- return float64(ret), nil
|
|
|
- case uint32:
|
|
|
- return float64(ret), nil
|
|
|
- case int32:
|
|
|
- return float64(ret), nil
|
|
|
- case uint64:
|
|
|
- return float64(ret), nil
|
|
|
- case int64:
|
|
|
- return float64(ret), nil
|
|
|
- case int:
|
|
|
- return float64(ret), nil
|
|
|
- case uint:
|
|
|
- return float64(ret), nil
|
|
|
- case float32:
|
|
|
- return float64(ret), nil
|
|
|
- case float64:
|
|
|
- return float64(ret), nil
|
|
|
- case string:
|
|
|
- floatVal, err := strconv.ParseFloat(ret, 64)
|
|
|
- if err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- return floatVal, nil
|
|
|
- default:
|
|
|
- return 0, fmt.Errorf("%v is not number", ret)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func getPath(val interface{}, keys ...interface{}) (interface{}, error) {
|
|
|
- if len(keys) == 0 {
|
|
|
- return val, nil
|
|
|
- }
|
|
|
- switch key := keys[0].(type) {
|
|
|
- case string:
|
|
|
- nextVal, err := getFromMap(val, key)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- nextKeys := make([]interface{}, len(keys)-1)
|
|
|
- copy(nextKeys, keys[1:])
|
|
|
- return getPath(nextVal, nextKeys...)
|
|
|
- case int:
|
|
|
- nextVal, err := getFromArray(val, key)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- nextKeys := make([]interface{}, len(keys)-1)
|
|
|
- copy(nextKeys, keys[1:])
|
|
|
- return getPath(nextVal, nextKeys...)
|
|
|
- default:
|
|
|
- return nil, fmt.Errorf("%v is not string or int", keys[0])
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func getFromMap(val interface{}, key string) (interface{}, error) {
|
|
|
- mapVal, ok := val.(map[string]interface{})
|
|
|
- if !ok {
|
|
|
- return nil, fmt.Errorf("%v is not map[string]interface{}", val)
|
|
|
- }
|
|
|
- ret, found := mapVal[key]
|
|
|
- if !found {
|
|
|
- return nil, fmt.Errorf("%v not found in %v", key, mapVal)
|
|
|
- }
|
|
|
- return ret, nil
|
|
|
-}
|
|
|
-
|
|
|
-func getFromArray(val interface{}, key int) (interface{}, error) {
|
|
|
- arrayVal, ok := val.([]interface{})
|
|
|
- if !ok {
|
|
|
- return nil, fmt.Errorf("%v is not []interface{}", val)
|
|
|
- }
|
|
|
- if key >= len(arrayVal) {
|
|
|
- return nil, fmt.Errorf("%v exceed %v", key, arrayVal)
|
|
|
- }
|
|
|
- if key < 0 {
|
|
|
- return nil, fmt.Errorf("%v exceed %v", key, arrayVal)
|
|
|
- }
|
|
|
- return arrayVal[key], nil
|
|
|
-}
|