diff --git a/json/json.go b/json/json.go new file mode 100644 index 0000000..ddaf3b9 --- /dev/null +++ b/json/json.go @@ -0,0 +1,14 @@ +//go:build !jsoniter +// +build !jsoniter + +package json + +import "encoding/json" + +var ( + Marshal = json.Marshal + Unmarshal = json.Unmarshal + MarshalIndent = json.MarshalIndent + NewDecoder = json.NewDecoder + NewEncoder = json.NewEncoder +) diff --git a/json/jsonconv.go b/json/jsonconv.go new file mode 100644 index 0000000..72fb2bb --- /dev/null +++ b/json/jsonconv.go @@ -0,0 +1,137 @@ +package json + +import ( + "bytes" + "log" + "regexp" + "strconv" + "strings" + "unicode" + + "github.com/charlienet/go-mixed/bytesconv" +) + +// 下划线 +type SnakeCase struct { + Value interface{} +} + +func (c SnakeCase) MarshalJSON() ([]byte, error) { + var keyMatchRegex = regexp.MustCompile(`\"(\w+)\":`) + var wordBarrierRegex = regexp.MustCompile(`(\w)([A-Z])`) + + marshalled, err := Marshal(c.Value) + converted := keyMatchRegex.ReplaceAllFunc( + marshalled, + func(match []byte) []byte { + return bytes.ToLower(wordBarrierRegex.ReplaceAll( + match, + bytesconv.StringToBytes(`${1}_${2}`), + )) + }, + ) + return converted, err +} + +// 驼峰 +type CamelCase struct { + Value interface{} +} + +func (c CamelCase) MarshalJSON() ([]byte, error) { + var keyMatchRegex = regexp.MustCompile(`\"(\w+)\":`) + marshalled, err := Marshal(c.Value) + converted := keyMatchRegex.ReplaceAllFunc( + marshalled, + func(match []byte) []byte { + matchStr := bytesconv.BytesToString(match) + key := matchStr[1 : len(matchStr)-2] + resKey := Lcfirst(Case2Camel(key)) + return bytesconv.StringToBytes(`"` + resKey + `":`) + }, + ) + return converted, err +} + +// 驼峰式写法转为下划线写法 +func Camel2Case(name string) string { + buffer := NewBuffer() + for i, r := range name { + if unicode.IsUpper(r) { + if i != 0 { + buffer.Append('_') + } + buffer.Append(unicode.ToLower(r)) + } else { + buffer.Append(r) + } + } + return buffer.String() +} + +// 下划线写法转为驼峰写法 +func Case2Camel(name string) string { + name = strings.Replace(name, "_", " ", -1) + // name = strings.Title(name) + return strings.Replace(name, " ", "", -1) +} + +func Case2CamelBytes(name []byte) []byte { + ret := Case2Camel(string(name)) + return bytesconv.StringToBytes(ret) +} + +// 首字母大写 +func Ucfirst(str string) string { + for i, v := range str { + return string(unicode.ToUpper(v)) + str[i+1:] + } + return "" +} + +// 首字母小写 +func Lcfirst(str string) string { + for i, v := range str { + return string(unicode.ToLower(v)) + str[i+1:] + } + return "" +} + +// 内嵌bytes.Buffer,支持连写 +type Buffer struct { + *bytes.Buffer +} + +func NewBuffer() *Buffer { + return &Buffer{Buffer: new(bytes.Buffer)} +} + +func (b *Buffer) Append(i interface{}) *Buffer { + switch val := i.(type) { + case int: + b.append(strconv.Itoa(val)) + case int64: + b.append(strconv.FormatInt(val, 10)) + case uint: + b.append(strconv.FormatUint(uint64(val), 10)) + case uint64: + b.append(strconv.FormatUint(val, 10)) + case string: + b.append(val) + case []byte: + b.Write(val) + case rune: + b.WriteRune(val) + } + return b +} + +func (b *Buffer) append(s string) *Buffer { + defer func() { + if err := recover(); err != nil { + log.Println("*****内存不够了!******") + } + }() + b.WriteString(s) + return b +} diff --git a/json/jsoniter.go b/json/jsoniter.go new file mode 100644 index 0000000..1a105ed --- /dev/null +++ b/json/jsoniter.go @@ -0,0 +1,15 @@ +//go:build jsoniter +// +build jsoniter + +package json + +import jsoniter "github.com/json-iterator/go" + +var ( + json = jsoniter.ConfigCompatibleWithStandardLibrary + Marshal = json.Marshal + Unmarshal = json.Unmarshal + MarshalIndent = json.MarshalIndent + NewDecoder = json.NewDecoder + NewEncoder = json.NewEncoder +) diff --git a/json/structConvert.go b/json/structConvert.go new file mode 100644 index 0000000..4e4dd70 --- /dev/null +++ b/json/structConvert.go @@ -0,0 +1,54 @@ +package json + +import ( + "reflect" + + "github.com/charlienet/go-mixed/bytesconv" +) + +// 结构转换为json字符串 +func StructToJsonIndent(obj interface{}) string { + b, _ := MarshalIndent(obj, "", " ") + return bytesconv.BytesToString(b) +} + +// 结构转换为json字符串 +func StructToJson(obj interface{}) string { + b, _ := Marshal(obj) + return bytesconv.BytesToString(b) +} + +func StructToMap(obj interface{}) map[string]interface{} { + typ := reflect.TypeOf(obj) + + kind := typ.Kind() + if kind == reflect.Map { + return toMap(obj) + } + + val := reflect.ValueOf(obj) + + m := make(map[string]interface{}) + for i := 0; i < val.NumField(); i++ { + m[typ.Field(i).Name] = val.Field(i).Interface() + } + + return m +} + +func StructToMapViaJson(obj interface{}) map[string]interface{} { + m := make(map[string]interface{}) + + j, _ := Marshal(obj) + _ = Unmarshal(j, &m) + + return m +} + +func toMap(obj interface{}) map[string]interface{} { + if h, ok := obj.(map[string]interface{}); ok { + return h + } + + return StructToMapViaJson(obj) +}