mirror of
https://github.com/yusing/godoxy.git
synced 2026-03-25 02:21:05 +01:00
feat: custom json marshaling implementation, replace json and yaml library (#89)
* chore: replace gopkg.in/yaml.v3 vs goccy/go-yaml; replace encoding/json with bytedance/sonic * fix: yaml unmarshal panic * feat: custom json marshaler implementation * chore: fix import and err marshal handling --------- Co-authored-by: yusing <yusing@6uo.me>
This commit is contained in:
70
pkg/json/json.go
Normal file
70
pkg/json/json.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
)
|
||||
|
||||
type Marshaler interface {
|
||||
MarshalJSONTo(buf []byte) []byte
|
||||
}
|
||||
|
||||
var (
|
||||
Unmarshal = sonic.Unmarshal
|
||||
Valid = sonic.Valid
|
||||
NewDecoder = sonic.ConfigDefault.NewDecoder
|
||||
)
|
||||
|
||||
// Marshal returns the JSON encoding of v.
|
||||
//
|
||||
// It's like json.Marshal, but with some differences:
|
||||
//
|
||||
// - It's ~4-5x faster in most cases.
|
||||
//
|
||||
// - It also supports custom Marshaler interface (MarshalJSONTo(buf []byte) []byte)
|
||||
// to allow further optimizations.
|
||||
//
|
||||
// - It leverages the strutils library.
|
||||
//
|
||||
// - It drops the need to implement Marshaler or json.Marshaler by supports extra field tags:
|
||||
//
|
||||
// `byte_size` to format the field to human readable size.
|
||||
//
|
||||
// `unix_time` to format the uint64 field to string date-time without specifying MarshalJSONTo.
|
||||
//
|
||||
// `use_marshaler` to force using the custom marshaler for primitive types declaration (e.g. `type Status int`).
|
||||
//
|
||||
// - It correct the behavior of *url.URL and time.Duration.
|
||||
//
|
||||
// - It does not support maps other than string-keyed maps.
|
||||
func Marshal(v any) ([]byte, error) {
|
||||
buf := newBytes()
|
||||
defer putBytes(buf)
|
||||
return cloneBytes(appendMarshal(reflect.ValueOf(v), buf)), nil
|
||||
}
|
||||
|
||||
func MarshalTo(v any, buf []byte) []byte {
|
||||
return appendMarshal(reflect.ValueOf(v), buf)
|
||||
}
|
||||
|
||||
const bufSize = 1024
|
||||
|
||||
var bytesPool = sync.Pool{
|
||||
New: func() any {
|
||||
return make([]byte, 0, bufSize)
|
||||
},
|
||||
}
|
||||
|
||||
func newBytes() []byte {
|
||||
return bytesPool.Get().([]byte)
|
||||
}
|
||||
|
||||
func putBytes(buf []byte) {
|
||||
bytesPool.Put(buf[:0])
|
||||
}
|
||||
|
||||
func cloneBytes(buf []byte) (res []byte) {
|
||||
return append(res, buf...)
|
||||
}
|
||||
Reference in New Issue
Block a user