github.com/uuosio/chaintester@v0.0.0-20230731100329-1f6fad7372e5/jsonvalue.go (about)

     1  package chaintester
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"strconv"
     8  	"strings"
     9  	"time"
    10  
    11  	traceable_errors "github.com/go-errors/errors"
    12  )
    13  
    14  var DEBUG = true
    15  
    16  func newError(err error) error {
    17  	if DEBUG {
    18  		if _, ok := err.(*traceable_errors.Error); ok {
    19  			return err
    20  		}
    21  		return traceable_errors.New(err.Error())
    22  	} else {
    23  		return err
    24  	}
    25  }
    26  
    27  func newErrorf(format string, args ...interface{}) error {
    28  	errMsg := fmt.Sprintf(format, args...)
    29  	if DEBUG {
    30  		return traceable_errors.New(errMsg)
    31  	} else {
    32  		return errors.New(errMsg)
    33  	}
    34  }
    35  
    36  type JsonValue struct {
    37  	raw   []byte
    38  	value interface{}
    39  }
    40  
    41  func NewJsonValue(value []byte) *JsonValue {
    42  	ret := &JsonValue{}
    43  	ret.raw = value
    44  	err := json.Unmarshal(value, ret)
    45  	if err == nil {
    46  		return ret
    47  	}
    48  	return nil
    49  }
    50  
    51  func (b *JsonValue) GetValue() interface{} {
    52  	return b.value
    53  }
    54  
    55  func (b *JsonValue) SetValue(value interface{}) error {
    56  	switch value.(type) {
    57  	case string, []JsonValue, map[string]JsonValue:
    58  		b.value = value
    59  		return nil
    60  	default:
    61  		panic("value must be a string, slice, or map")
    62  	}
    63  	return nil
    64  }
    65  
    66  func parseSubValue(subValue *JsonValue) interface{} {
    67  	switch v := subValue.value.(type) {
    68  	case string:
    69  		return strings.Trim(v, "\"")
    70  	case []JsonValue, map[string]JsonValue:
    71  		return subValue.value
    72  	}
    73  	return subValue
    74  }
    75  
    76  func (b *JsonValue) GetStringValue() (string, bool) {
    77  	switch v := b.value.(type) {
    78  	case string:
    79  		return strings.Trim(v, "\""), true
    80  	default:
    81  		return "", false
    82  	}
    83  }
    84  
    85  //return string, []JsonValue, or map[string]JsonValue
    86  func (b *JsonValue) Get(keys ...interface{}) (interface{}, error) {
    87  	if len(keys) == 0 {
    88  		return JsonValue{}, newErrorf("no key specified")
    89  	}
    90  
    91  	value := b.value
    92  	for _, key := range keys {
    93  		switch v := key.(type) {
    94  		case string:
    95  			switch v2 := value.(type) {
    96  			case map[string]JsonValue:
    97  				subValue, ok := v2[v]
    98  				if !ok {
    99  					return nil, newErrorf("key not found")
   100  				}
   101  				value = parseSubValue(&subValue)
   102  			case JsonValue:
   103  				v3, ok := v2.value.(map[string]JsonValue)
   104  				if !ok {
   105  					return JsonValue{}, newErrorf("1:JsonValue is not a map")
   106  				}
   107  				subValue, ok := v3[v]
   108  				if !ok {
   109  					return nil, newErrorf("key not found")
   110  				}
   111  				value = parseSubValue(&subValue)
   112  			default:
   113  				return JsonValue{}, newErrorf("2:JsonValue is not a map")
   114  			}
   115  		case int:
   116  			var arr []JsonValue
   117  			var ok bool
   118  			switch _v := value.(type) {
   119  			case []JsonValue:
   120  				arr = _v
   121  			case JsonValue:
   122  				arr, ok = _v.value.([]JsonValue)
   123  				if !ok {
   124  					return JsonValue{}, newErrorf("JsonValue is not an array")
   125  				}
   126  			default:
   127  				return JsonValue{}, newErrorf("JsonValue is not an array")
   128  			}
   129  			if v < 0 || v >= len(arr) {
   130  				return JsonValue{}, newErrorf("index out of range")
   131  			}
   132  			value = parseSubValue(&arr[v])
   133  		default:
   134  			return JsonValue{}, newErrorf("invalid key type")
   135  		}
   136  	}
   137  	return value, nil
   138  }
   139  
   140  func (b *JsonValue) GetString(keys ...interface{}) (string, error) {
   141  	v, err := b.Get(keys...)
   142  	if err != nil {
   143  		return "", err
   144  	}
   145  
   146  	switch _v := v.(type) {
   147  	case string:
   148  		return _v, nil
   149  	case map[string]JsonValue:
   150  		__v, err := json.Marshal(_v)
   151  		if err != nil {
   152  			return "", err
   153  		}
   154  		return string(__v), nil
   155  	case []JsonValue:
   156  		__v, err := json.Marshal(_v)
   157  		if err != nil {
   158  			return "", err
   159  		}
   160  		return string(__v), nil
   161  	default:
   162  		return "", newErrorf("invalid json value")
   163  	}
   164  	return "", newErrorf("invalid json value!")
   165  }
   166  
   167  func (b *JsonValue) GetTime(keys ...interface{}) (*time.Time, error) {
   168  	v, err := b.GetString(keys...)
   169  	if err != nil {
   170  		return nil, err
   171  	}
   172  
   173  	t, err := time.Parse("2006-01-02T15:04:05", v)
   174  	if err != nil {
   175  		return nil, err
   176  	}
   177  	return &t, nil
   178  }
   179  
   180  func (b JsonValue) MarshalJSON() ([]byte, error) {
   181  	switch v := b.value.(type) {
   182  	case string:
   183  		if _, err := strconv.ParseInt(v, 10, 64); err == nil {
   184  			return []byte(v), nil
   185  		} else {
   186  			return []byte(v), nil //[]byte(strconv.Quote(v)), nil
   187  		}
   188  	case JsonValue:
   189  		if s, ok := v.value.(string); ok {
   190  			return []byte(s), nil
   191  		}
   192  		return json.Marshal(v.value)
   193  	case map[string]JsonValue:
   194  		return json.Marshal(v)
   195  	case []JsonValue:
   196  		return json.Marshal(v)
   197  	}
   198  	return nil, newErrorf("bad JsonValue")
   199  }
   200  
   201  func (b *JsonValue) UnmarshalJSON(data []byte) error {
   202  	// fmt.Println("+++++:UnmarshaJSON", string(data))
   203  	if data[0] == '{' {
   204  		m := make(map[string]JsonValue)
   205  		err := json.Unmarshal(data, &m)
   206  		if err != nil {
   207  			return newError(err)
   208  		}
   209  		b.raw = data
   210  		b.value = m
   211  	} else if data[0] == '[' {
   212  		m := make([]JsonValue, 0, 1)
   213  		err := json.Unmarshal(data, &m)
   214  		if err != nil {
   215  			return newError(err)
   216  		}
   217  		b.raw = data
   218  		b.value = m
   219  	} else {
   220  		b.raw = data
   221  		b.value = string(data)
   222  	}
   223  	return nil
   224  }
   225  
   226  func (b *JsonValue) ToString() string {
   227  	return string(b.raw)
   228  	// value, _ := json.Marshal(b.value)
   229  	// return string(value)
   230  }