github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/adapter.go (about) 1 package jsoni 2 3 import ( 4 "bytes" 5 "context" 6 "io" 7 ) 8 9 // RawMessage to make replace json with jsoniter 10 type RawMessage []byte 11 12 // Unmarshal adapts to json/encoding Unmarshal API 13 // 14 // Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. 15 // Refer to https://godoc.org/encoding/json#Unmarshal for more information 16 func Unmarshal(data []byte, v interface{}) error { 17 return UnmarshalContext(context.Background(), data, v) 18 } 19 20 func UnmarshalContext(ctx context.Context, data []byte, v interface{}) error { 21 return ConfigDefault.Unmarshal(ctx, data, v) 22 } 23 24 // UnmarshalFromString is a convenient method to read from string instead of []byte 25 func UnmarshalFromString(str string, v interface{}) error { 26 return UnmarshalFromStringContext(context.Background(), str, v) 27 } 28 29 func UnmarshalFromStringContext(ctx context.Context, str string, v interface{}) error { 30 return ConfigDefault.UnmarshalFromString(ctx, str, v) 31 } 32 33 // Get quick method to get value from deeply nested JSON structure 34 func Get(data []byte, path ...interface{}) Any { 35 return ConfigDefault.Get(data, path...) 36 } 37 38 // Marshal adapts to json/encoding Marshal API 39 // 40 // Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API 41 // Refer to https://godoc.org/encoding/json#Marshal for more information 42 func Marshal(v interface{}) ([]byte, error) { 43 return MarshalContext(context.Background(), v) 44 } 45 46 func MarshalContext(ctx context.Context, v interface{}) ([]byte, error) { 47 return ConfigDefault.Marshal(ctx, v) 48 } 49 50 // MarshalIndent same as json.MarshalIndent. Prefix is not supported. 51 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { 52 return MarshalIndentContext(context.Background(), v, prefix, indent) 53 } 54 55 func MarshalIndentContext(ctx context.Context, v interface{}, prefix, indent string) ([]byte, error) { 56 return ConfigDefault.MarshalIndent(ctx, v, prefix, indent) 57 } 58 59 // MarshalToString convenient method to write as string instead of []byte 60 func MarshalToString(v interface{}) (string, error) { 61 return MarshalToStringContext(context.Background(), v) 62 } 63 64 func MarshalToStringContext(ctx context.Context, v interface{}) (string, error) { 65 return ConfigDefault.MarshalToString(ctx, v) 66 } 67 68 // NewDecoder adapts to json/stream NewDecoder API. 69 // 70 // NewDecoder returns a new decoder that reads from r. 71 // 72 // Instead of a json/encoding Decoder, an Decoder is returned 73 // Refer to https://godoc.org/encoding/json#NewDecoder for more information 74 func NewDecoder(reader io.Reader) *Decoder { 75 return ConfigDefault.NewDecoder(reader) 76 } 77 78 // Decoder reads and decodes JSON values from an input stream. 79 // Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) 80 type Decoder struct { 81 iter *Iterator 82 } 83 84 // Decode decode JSON into interface{} 85 func (a *Decoder) Decode(ctx context.Context, obj interface{}) error { 86 if a.iter.head == a.iter.tail && a.iter.reader != nil { 87 if !a.iter.loadMore() { 88 return io.EOF 89 } 90 } 91 a.iter.ReadVal(ctx, obj) 92 err := a.iter.Error 93 if err == io.EOF { 94 return nil 95 } 96 return a.iter.Error 97 } 98 99 // More is there more? 100 func (a *Decoder) More() bool { 101 iter := a.iter 102 if iter.Error != nil { 103 return false 104 } 105 c := iter.nextToken() 106 if c == 0 { 107 return false 108 } 109 iter.unreadByte() 110 return c != ']' && c != '}' 111 } 112 113 // Buffered remaining buffer 114 func (a *Decoder) Buffered() io.Reader { 115 remaining := a.iter.buf[a.iter.head:a.iter.tail] 116 return bytes.NewReader(remaining) 117 } 118 119 // UseNumber causes the Decoder to unmarshal a number into an interface{} as a 120 // Number instead of as a float64. 121 func (a *Decoder) UseNumber() { 122 cfg := a.iter.cfg.configBeforeFrozen 123 cfg.UseNumber = true 124 a.iter.cfg = cfg.frozeWithCacheReuse(a.iter.cfg.extensions) 125 } 126 127 // DisallowUnknownFields causes the Decoder to return an error when the destination 128 // is a struct and the input contains object keys which do not match any 129 // non-ignored, exported fields in the destination. 130 func (a *Decoder) DisallowUnknownFields() { 131 cfg := a.iter.cfg.configBeforeFrozen 132 cfg.DisallowUnknownFields = true 133 a.iter.cfg = cfg.frozeWithCacheReuse(a.iter.cfg.extensions) 134 } 135 136 // NewEncoder same as json.NewEncoder 137 func NewEncoder(writer io.Writer) *Encoder { 138 return ConfigDefault.NewEncoder(writer) 139 } 140 141 // Encoder same as json.Encoder 142 type Encoder struct { 143 stream *Stream 144 } 145 146 // Encode encode interface{} as JSON to io.Writer 147 func (a *Encoder) Encode(ctx context.Context, val interface{}) error { 148 a.stream.WriteVal(ctx, val) 149 a.stream.WriteRaw("\n") 150 a.stream.Flush() 151 return a.stream.Error 152 } 153 154 // SetIndent set the indention. Prefix is not supported 155 func (a *Encoder) SetIndent(prefix, indent string) { 156 config := a.stream.cfg.configBeforeFrozen 157 config.IndentionStep = len(indent) 158 a.stream.cfg = config.frozeWithCacheReuse(a.stream.cfg.extensions) 159 } 160 161 // SetEscapeHTML escape html by default, set to false to disable 162 func (a *Encoder) SetEscapeHTML(escapeHTML bool) { 163 config := a.stream.cfg.configBeforeFrozen 164 config.EscapeHTML = escapeHTML 165 a.stream.cfg = config.frozeWithCacheReuse(a.stream.cfg.extensions) 166 } 167 168 // Valid reports whether data is a valid JSON encoding. 169 func Valid(data []byte) bool { 170 return ValidContext(context.Background(), data) 171 } 172 173 func ValidJSON(data []byte) bool { 174 return ValidJSONContext(context.Background(), data) 175 } 176 177 func ValidJSONContext(ctx context.Context, s []byte) bool { 178 return ValidContext(ctx, s) && (s[0] == '{' || s[0] == '[') 179 } 180 181 func ValidContext(ctx context.Context, data []byte) bool { 182 return ConfigDefault.Valid(ctx, data) 183 }