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  }