1 Star 0 Fork 0

一只北京的小修狗/测试自动化

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
jsonutil.go 6.06 KB
一键复制 编辑 原始数据 按行查看 历史
一只北京的小修狗 提交于 2024-10-02 13:15 +08:00 . 测试
package jsonutil
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"gitee.com/beijingxiugo/GolandAuto/log"
"gitee.com/beijingxiugo/GolandAuto/process"
"github.com/bitly/go-simplejson"
diff "github.com/nsf/jsondiff"
"reflect"
"regexp"
"strconv"
"strings"
)
var jsonOutputOpts diff.Options
var consoleOutputOpts diff.Options
func init() {
jsonOutputOpts = diff.DefaultJSONOptions()
consoleOutputOpts = diff.DefaultConsoleOptions()
}
func DiffString(a, b string) (bool, string) {
return DiffByte([]byte(a), []byte(b))
}
func DiffByte(a, b []byte) (bool, string) {
r, d := diff.Compare(a, b, &jsonOutputOpts)
return r == diff.FullMatch, d
}
func DiffStringWithConsole(a, b string) (bool, string) {
return DiffByte([]byte(a), []byte(b))
}
func DiffByteWithConsole(a, b []byte) (bool, string) {
r, d := diff.Compare(a, b, &consoleOutputOpts)
return r == diff.FullMatch, d
}
func JsonMarshal(v interface{}) string {
b, err := json.Marshal(v)
if err != nil {
log.Warn("JsonMarshal failed for v: %+v, err: %v", v, err)
return `{"err_msg": "not json format"}`
}
return string(b)
}
func JsonMarshalIndent(v interface{}) string {
b, err := json.MarshalIndent(v, "", " ")
if err != nil {
log.Warn("JsonMarshal failed for v: %+v", v)
return `{"err_msg": "not json format"}`
}
return string(b)
}
func JsonMarshal2interface(from, to interface{}) error {
b, err := json.Marshal(from)
if err != nil {
log.Warn("JsonMarshal failed for v: %+v, err: %v", from, err)
return err
}
err = json.Unmarshal(b, to)
if err != nil {
log.Warn("JsonUnmarshal failed for v: %+v, err: %v", to, err)
return err
}
return nil
}
func Json2Map(jsonStr string) (map[string]interface{}, error) {
if jsonStr == "" {
return nil, errors.New("jsonStr is empty")
}
m := make(map[string]interface{})
err := json.Unmarshal([]byte(jsonStr), &m)
if err != nil {
fmt.Sprintf("Unmarshal with error : %+v", err)
return nil, err
}
return m, nil
}
func getArrayIdx(key string) int {
if strings.Contains(key, "[") {
idx, _ := strconv.Atoi(key[strings.Index(key, "[")+1 : len(key)-1])
return idx
}
return -1
}
func getArrayKeyName(key string) string {
if strings.Contains(key, "[") {
idx := key[0:strings.Index(key, "[")]
return idx
} else {
return key
}
}
func UpdateJson(path string, m interface{}, val interface{}) (interface{}, error) {
pathSplit := strings.Split(path, ".")
_type := reflect.TypeOf(m)
kind := _type.Kind()
if !(kind == reflect.Map || kind == reflect.Struct) {
return m, nil
}
m = m.(map[string]interface{})
ret, _ := HandleJsonMap(m, pathSplit[0], val, path)
var res map[string]interface{}
e := json.Unmarshal([]byte(process.MustToJsonString(ret)), &res)
if e != nil {
log.Print(e.Error())
}
return res, nil
}
func HandleJsonArray(m interface{}, key string, nVal interface{}, path string) (interface{}, error) {
ret, _ := simplejson.NewJson([]byte(process.MustToJsonString(m)))
_type := reflect.TypeOf(m)
kind := _type.Kind()
arrIdx := getArrayIdx(key)
if isArrKey(key) && arrIdx == -1 {
ret.Set(key, nVal)
return ret, nil
}
pathSplit := strings.Split(path, ".")
restPath := getRestPath(path, key)
if kind == reflect.Slice || kind == reflect.Array {
arr := m.([]interface{})
for idx, node := range arr {
_type = reflect.TypeOf(node)
kind = _type.Kind()
if kind == reflect.Map && restPath != "" {
if idx == arrIdx {
_json, _ := HandleJsonMap(node, pathSplit[0], nVal, path)
arr[idx] = _json
} else {
arr[idx] = node
}
} else {
if idx == arrIdx {
arr[idx] = nVal
} else {
arr[idx] = node
}
}
}
var res []interface{}
e := json.Unmarshal([]byte(process.MustToJsonString(arr)), &res)
if e != nil {
log.Print(e.Error())
}
return res, nil
}
return m, nil
}
func HandleJsonMap(m interface{}, key string, val interface{}, path string) (interface{}, error) {
pathSplit := strings.Split(path, ".")
restPath := getRestPath(path, key)
_m := m.(map[string]interface{})
_isArrKey := isArrKey(key)
if _isArrKey {
key = getArrayKeyName(key)
}
if v, ok := _m[key]; ok {
_type := reflect.TypeOf(v)
kind := _type.Kind()
if restPath == "" && !_isArrKey {
_m[key] = val
return _m, nil
}
if kind == reflect.Array || kind == reflect.Slice {
js, _ := HandleJsonArray(v, pathSplit[0], val, restPath)
_m[key] = js
return _m, nil
} else if kind == reflect.Map {
js, _ := HandleJsonMap(v, pathSplit[1], val, restPath)
_m[key] = js
return _m, nil
} else {
_m[key] = val
return _m, nil
}
}
return m, nil
}
func getRestPath(path, key string) string {
restPath := strings.ReplaceAll(path, key, "")
if strings.HasPrefix(restPath, ".") {
restPath = restPath[1:]
}
return restPath
}
func isArrKey(key string) bool {
r := regexp.MustCompile("\\[[0-9]+\\]")
return r.MatchString(key)
}
func GetJsonPath(m interface{}, name string, res map[string]interface{}, path string) (string, map[string]interface{}) {
_type := reflect.TypeOf(m)
kind := _type.Kind()
switch kind {
case reflect.Map, reflect.Struct:
_m := m.(map[string]interface{})
for k, v := range _m {
_type = reflect.TypeOf(v)
kind = _type.Kind()
if kind == reflect.Map || kind == reflect.Struct {
path += "." + k
path, res = GetJsonPath(v, k, res, path)
path = returnPre(path)
} else if kind == reflect.Array || kind == reflect.Slice {
arr := v.([]interface{})
for idx, item := range arr {
path += "." + k + "[" + strconv.Itoa(idx) + "]"
path, res = GetJsonPath(item, name, res, path)
res[path] = item
path = returnPre(path)
}
} else {
path += "." + k
res[path] = v
path = returnPre(path)
}
}
}
return path, res
}
func returnPre(path string) string {
pathSplit := strings.Split(path, ".")
pathSplit = pathSplit[:len(pathSplit)-1]
return strings.Join(pathSplit, ".")
}
func JsonDecode(source interface{}, dst interface{}) error {
_bytes, _ := json.Marshal(source)
decoder := json.NewDecoder(bytes.NewBufferString(string(_bytes)))
decoder.UseNumber()
err := decoder.Decode(dst)
if err != nil {
log.Errorf("Decode failed")
}
return err
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/beijingxiugo/GolandAuto.git
git@gitee.com:beijingxiugo/GolandAuto.git
beijingxiugo
GolandAuto
测试自动化
v0.2.1

搜索帮助