github.com/grbit/go-json@v0.11.0/json.go (about)

     1  package json
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  
     8  	"github.com/grbit/go-json/internal/encoder"
     9  )
    10  
    11  // Marshaler is the interface implemented by types that
    12  // can marshal themselves into valid JSON.
    13  type Marshaler interface {
    14  	MarshalJSON() ([]byte, error)
    15  }
    16  
    17  // MarshalerContext is the interface implemented by types that
    18  // can marshal themselves into valid JSON with context.Context.
    19  type MarshalerContext interface {
    20  	MarshalJSON(context.Context) ([]byte, error)
    21  }
    22  
    23  // Unmarshaler is the interface implemented by types
    24  // that can unmarshal a JSON description of themselves.
    25  // The input can be assumed to be a valid encoding of
    26  // a JSON value. UnmarshalJSON must copy the JSON data
    27  // if it wishes to retain the data after returning.
    28  //
    29  // By convention, to approximate the behavior of Unmarshal itself,
    30  // Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
    31  type Unmarshaler interface {
    32  	UnmarshalJSON([]byte) error
    33  }
    34  
    35  // UnmarshalerContext is the interface implemented by types
    36  // that can unmarshal with context.Context a JSON description of themselves.
    37  type UnmarshalerContext interface {
    38  	UnmarshalJSON(context.Context, []byte) error
    39  }
    40  
    41  // Marshal returns the JSON encoding of v.
    42  //
    43  // Marshal traverses the value v recursively.
    44  // If an encountered value implements the Marshaler interface
    45  // and is not a nil pointer, Marshal calls its MarshalJSON method
    46  // to produce JSON. If no MarshalJSON method is present but the
    47  // value implements encoding.TextMarshaler instead, Marshal calls
    48  // its MarshalText method and encodes the result as a JSON string.
    49  // The nil pointer exception is not strictly necessary
    50  // but mimics a similar, necessary exception in the behavior of
    51  // UnmarshalJSON.
    52  //
    53  // Otherwise, Marshal uses the following type-dependent default encodings:
    54  //
    55  // Boolean values encode as JSON booleans.
    56  //
    57  // Floating point, integer, and Number values encode as JSON numbers.
    58  //
    59  // String values encode as JSON strings coerced to valid UTF-8,
    60  // replacing invalid bytes with the Unicode replacement rune.
    61  // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
    62  // to keep some browsers from misinterpreting JSON output as HTML.
    63  // Ampersand "&" is also escaped to "\u0026" for the same reason.
    64  // This escaping can be disabled using an Encoder that had SetEscapeHTML(false)
    65  // called on it.
    66  //
    67  // Array and slice values encode as JSON arrays, except that
    68  // []byte encodes as a base64-encoded string, and a nil slice
    69  // encodes as the null JSON value.
    70  //
    71  // Struct values encode as JSON objects.
    72  // Each exported struct field becomes a member of the object, using the
    73  // field name as the object key, unless the field is omitted for one of the
    74  // reasons given below.
    75  //
    76  // The encoding of each struct field can be customized by the format string
    77  // stored under the "json" key in the struct field's tag.
    78  // The format string gives the name of the field, possibly followed by a
    79  // comma-separated list of options. The name may be empty in order to
    80  // specify options without overriding the default field name.
    81  //
    82  // The "omitempty" option specifies that the field should be omitted
    83  // from the encoding if the field has an empty value, defined as
    84  // false, 0, a nil pointer, a nil interface value, and any empty array,
    85  // slice, map, or string.
    86  //
    87  // As a special case, if the field tag is "-", the field is always omitted.
    88  // Note that a field with name "-" can still be generated using the tag "-,".
    89  //
    90  // Examples of struct field tags and their meanings:
    91  //
    92  //	// Field appears in JSON as key "myName".
    93  //	Field int `json:"myName"`
    94  //
    95  //	// Field appears in JSON as key "myName" and
    96  //	// the field is omitted from the object if its value is empty,
    97  //	// as defined above.
    98  //	Field int `json:"myName,omitempty"`
    99  //
   100  //	// Field appears in JSON as key "Field" (the default), but
   101  //	// the field is skipped if empty.
   102  //	// Note the leading comma.
   103  //	Field int `json:",omitempty"`
   104  //
   105  //	// Field is ignored by this package.
   106  //	Field int `json:"-"`
   107  //
   108  //	// Field appears in JSON as key "-".
   109  //	Field int `json:"-,"`
   110  //
   111  // The "string" option signals that a field is stored as JSON inside a
   112  // JSON-encoded string. It applies only to fields of string, floating point,
   113  // integer, or boolean types. This extra level of encoding is sometimes used
   114  // when communicating with JavaScript programs:
   115  //
   116  //	Int64String int64 `json:",string"`
   117  //
   118  // The key name will be used if it's a non-empty string consisting of
   119  // only Unicode letters, digits, and ASCII punctuation except quotation
   120  // marks, backslash, and comma.
   121  //
   122  // Anonymous struct fields are usually marshaled as if their inner exported fields
   123  // were fields in the outer struct, subject to the usual Go visibility rules amended
   124  // as described in the next paragraph.
   125  // An anonymous struct field with a name given in its JSON tag is treated as
   126  // having that name, rather than being anonymous.
   127  // An anonymous struct field of interface type is treated the same as having
   128  // that type as its name, rather than being anonymous.
   129  //
   130  // The Go visibility rules for struct fields are amended for JSON when
   131  // deciding which field to marshal or unmarshal. If there are
   132  // multiple fields at the same level, and that level is the least
   133  // nested (and would therefore be the nesting level selected by the
   134  // usual Go rules), the following extra rules apply:
   135  //
   136  // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
   137  // even if there are multiple untagged fields that would otherwise conflict.
   138  //
   139  // 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
   140  //
   141  // 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
   142  //
   143  // Handling of anonymous struct fields is new in Go 1.1.
   144  // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
   145  // an anonymous struct field in both current and earlier versions, give the field
   146  // a JSON tag of "-".
   147  //
   148  // Map values encode as JSON objects. The map's key type must either be a
   149  // string, an integer type, or implement encoding.TextMarshaler. The map keys
   150  // are sorted and used as JSON object keys by applying the following rules,
   151  // subject to the UTF-8 coercion described for string values above:
   152  //   - string keys are used directly
   153  //   - encoding.TextMarshalers are marshaled
   154  //   - integer keys are converted to strings
   155  //
   156  // Pointer values encode as the value pointed to.
   157  // A nil pointer encodes as the null JSON value.
   158  //
   159  // Interface values encode as the value contained in the interface.
   160  // A nil interface value encodes as the null JSON value.
   161  //
   162  // Channel, complex, and function values cannot be encoded in JSON.
   163  // Attempting to encode such a value causes Marshal to return
   164  // an UnsupportedTypeError.
   165  //
   166  // JSON cannot represent cyclic data structures and Marshal does not
   167  // handle them. Passing cyclic structures to Marshal will result in
   168  // an infinite recursion.
   169  func Marshal(v interface{}) (b []byte, err error) {
   170  	defer func() {
   171  		if r := recover(); r != nil {
   172  			b, err = json.Marshal(v)
   173  
   174  			return
   175  		}
   176  	}()
   177  
   178  	b, err = MarshalWithOption(v)
   179  	if err != nil {
   180  		b, err = json.Marshal(v)
   181  	}
   182  
   183  	return b, err
   184  }
   185  
   186  // MarshalNoEscape returns the JSON encoding of v and doesn't escape v.
   187  func MarshalNoEscape(v interface{}) ([]byte, error) {
   188  	return marshalNoEscape(v)
   189  }
   190  
   191  // MarshalContext returns the JSON encoding of v with context.Context and EncodeOption.
   192  func MarshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) {
   193  	return marshalContext(ctx, v, optFuncs...)
   194  }
   195  
   196  // MarshalWithOption returns the JSON encoding of v with EncodeOption.
   197  func MarshalWithOption(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) {
   198  	return marshal(v, optFuncs...)
   199  }
   200  
   201  // MarshalIndent is like Marshal but applies Indent to format the output.
   202  // Each JSON element in the output will begin on a new line beginning with prefix
   203  // followed by one or more copies of indent according to the indentation nesting.
   204  func MarshalIndent(v interface{}, prefix, indent string) (b []byte, err error) {
   205  	defer func() {
   206  		if r := recover(); r != nil {
   207  			b, err = json.MarshalIndent(v, prefix, indent)
   208  
   209  			return
   210  		}
   211  	}()
   212  
   213  	b, err = MarshalIndentWithOption(v, prefix, indent)
   214  	if err != nil {
   215  		b, err = json.MarshalIndent(v, prefix, indent)
   216  	}
   217  
   218  	return b, err
   219  }
   220  
   221  // MarshalIndentWithOption is like Marshal but applies Indent to format the output with EncodeOption.
   222  func MarshalIndentWithOption(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) {
   223  	return marshalIndent(v, prefix, indent, optFuncs...)
   224  }
   225  
   226  // Unmarshal parses the JSON-encoded data and stores the result
   227  // in the value pointed to by v. If v is nil or not a pointer,
   228  // Unmarshal returns an InvalidUnmarshalError.
   229  //
   230  // Unmarshal uses the inverse of the encodings that
   231  // Marshal uses, allocating maps, slices, and pointers as necessary,
   232  // with the following additional rules:
   233  //
   234  // To unmarshal JSON into a pointer, Unmarshal first handles the case of
   235  // the JSON being the JSON literal null. In that case, Unmarshal sets
   236  // the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
   237  // the value pointed at by the pointer. If the pointer is nil, Unmarshal
   238  // allocates a new value for it to point to.
   239  //
   240  // To unmarshal JSON into a value implementing the Unmarshaler interface,
   241  // Unmarshal calls that value's UnmarshalJSON method, including
   242  // when the input is a JSON null.
   243  // Otherwise, if the value implements encoding.TextUnmarshaler
   244  // and the input is a JSON quoted string, Unmarshal calls that value's
   245  // UnmarshalText method with the unquoted form of the string.
   246  //
   247  // To unmarshal JSON into a struct, Unmarshal matches incoming object
   248  // keys to the keys used by Marshal (either the struct field name or its tag),
   249  // preferring an exact match but also accepting a case-insensitive match. By
   250  // default, object keys which don't have a corresponding struct field are
   251  // ignored (see Decoder.DisallowUnknownFields for an alternative).
   252  //
   253  // To unmarshal JSON into an interface value,
   254  // Unmarshal stores one of these in the interface value:
   255  //
   256  //	bool, for JSON booleans
   257  //	float64, for JSON numbers
   258  //	string, for JSON strings
   259  //	[]interface{}, for JSON arrays
   260  //	map[string]interface{}, for JSON objects
   261  //	nil for JSON null
   262  //
   263  // To unmarshal a JSON array into a slice, Unmarshal resets the slice length
   264  // to zero and then appends each element to the slice.
   265  // As a special case, to unmarshal an empty JSON array into a slice,
   266  // Unmarshal replaces the slice with a new empty slice.
   267  //
   268  // To unmarshal a JSON array into a Go array, Unmarshal decodes
   269  // JSON array elements into corresponding Go array elements.
   270  // If the Go array is smaller than the JSON array,
   271  // the additional JSON array elements are discarded.
   272  // If the JSON array is smaller than the Go array,
   273  // the additional Go array elements are set to zero values.
   274  //
   275  // To unmarshal a JSON object into a map, Unmarshal first establishes a map to
   276  // use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal
   277  // reuses the existing map, keeping existing entries. Unmarshal then stores
   278  // key-value pairs from the JSON object into the map. The map's key type must
   279  // either be any string type, an integer, implement json.Unmarshaler, or
   280  // implement encoding.TextUnmarshaler.
   281  //
   282  // If a JSON value is not appropriate for a given target type,
   283  // or if a JSON number overflows the target type, Unmarshal
   284  // skips that field and completes the unmarshaling as best it can.
   285  // If no more serious errors are encountered, Unmarshal returns
   286  // an UnmarshalTypeError describing the earliest such error. In any
   287  // case, it's not guaranteed that all the remaining fields following
   288  // the problematic one will be unmarshaled into the target object.
   289  //
   290  // The JSON null value unmarshals into an interface, map, pointer, or slice
   291  // by setting that Go value to nil. Because null is often used in JSON to mean
   292  // “not present,” unmarshaling a JSON null into any other Go type has no effect
   293  // on the value and produces no error.
   294  //
   295  // When unmarshaling quoted strings, invalid UTF-8 or
   296  // invalid UTF-16 surrogate pairs are not treated as an error.
   297  // Instead, they are replaced by the Unicode replacement
   298  // character U+FFFD.
   299  func Unmarshal(data []byte, v interface{}) (err error) {
   300  	defer func() {
   301  		if r := recover(); r != nil {
   302  			err = json.Unmarshal(data, v)
   303  
   304  			return
   305  		}
   306  	}()
   307  
   308  	err = unmarshal(data, v)
   309  	if err != nil {
   310  		err = json.Unmarshal(data, v)
   311  	}
   312  
   313  	return err
   314  }
   315  
   316  // UnmarshalContext parses the JSON-encoded data and stores the result
   317  // in the value pointed to by v. If you implement the UnmarshalerContext interface,
   318  // call it with ctx as an argument.
   319  func UnmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
   320  	return unmarshalContext(ctx, data, v)
   321  }
   322  
   323  func UnmarshalWithOption(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
   324  	return unmarshal(data, v, optFuncs...)
   325  }
   326  
   327  func UnmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
   328  	return unmarshalNoEscape(data, v, optFuncs...)
   329  }
   330  
   331  // A Token holds a value of one of these types:
   332  //
   333  //	Delim, for the four JSON delimiters [ ] { }
   334  //	bool, for JSON booleans
   335  //	float64, for JSON numbers
   336  //	Number, for JSON numbers
   337  //	string, for JSON string literals
   338  //	nil, for JSON null
   339  type Token = json.Token
   340  
   341  // A Number represents a JSON number literal.
   342  type Number = json.Number
   343  
   344  // RawMessage is a raw encoded JSON value.
   345  // It implements Marshaler and Unmarshaler and can
   346  // be used to delay JSON decoding or precompute a JSON encoding.
   347  type RawMessage = json.RawMessage
   348  
   349  // A Delim is a JSON array or object delimiter, one of [ ] { or }.
   350  type Delim = json.Delim
   351  
   352  // Compact appends to dst the JSON-encoded src with
   353  // insignificant space characters elided.
   354  func Compact(dst *bytes.Buffer, src []byte) error {
   355  	return encoder.Compact(dst, src, false)
   356  }
   357  
   358  // Indent appends to dst an indented form of the JSON-encoded src.
   359  // Each element in a JSON object or array begins on a new,
   360  // indented line beginning with prefix followed by one or more
   361  // copies of indent according to the indentation nesting.
   362  // The data appended to dst does not begin with the prefix nor
   363  // any indentation, to make it easier to embed inside other formatted JSON data.
   364  // Although leading space characters (space, tab, carriage return, newline)
   365  // at the beginning of src are dropped, trailing space characters
   366  // at the end of src are preserved and copied to dst.
   367  // For example, if src has no trailing spaces, neither will dst;
   368  // if src ends in a trailing newline, so will dst.
   369  func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
   370  	return encoder.Indent(dst, src, prefix, indent)
   371  }
   372  
   373  // HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
   374  // characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
   375  // so that the JSON will be safe to embed inside HTML <script> tags.
   376  // For historical reasons, web browsers don't honor standard HTML
   377  // escaping within <script> tags, so an alternative JSON encoding must
   378  // be used.
   379  func HTMLEscape(dst *bytes.Buffer, src []byte) {
   380  	var v interface{}
   381  	dec := NewDecoder(bytes.NewBuffer(src))
   382  	dec.UseNumber()
   383  	if err := dec.Decode(&v); err != nil {
   384  		return
   385  	}
   386  	buf, _ := marshal(v)
   387  	dst.Write(buf)
   388  }
   389  
   390  // Valid reports whether data is a valid JSON encoding.
   391  func Valid(data []byte) bool {
   392  	var v interface{}
   393  	decoder := NewDecoder(bytes.NewReader(data))
   394  	err := decoder.Decode(&v)
   395  	if err != nil {
   396  		return false
   397  	}
   398  	if !decoder.More() {
   399  		return true
   400  	}
   401  	return decoder.InputOffset() >= int64(len(data))
   402  }
   403  
   404  func init() {
   405  	encoder.Marshal = Marshal
   406  	encoder.Unmarshal = Unmarshal
   407  }