| // Copyright 2010 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| //go:build goexperiment.jsonv2 |
| |
| // Package json implements encoding and decoding of JSON as defined in |
| // RFC 7159. The mapping between JSON and Go values is described |
| // in the documentation for the Marshal and Unmarshal functions. |
| // |
| // See "JSON and Go" for an introduction to this package: |
| // https://golang.org/doc/articles/json_and_go.html |
| // |
| // # Security Considerations |
| // |
| // See the "Security Considerations" section in [encoding/json/v2]. |
| // |
| // For historical reasons, the default behavior of v1 [encoding/json] |
| // unfortunately operates with less secure defaults. |
| // New usages of JSON in Go are encouraged to use [encoding/json/v2] instead. |
| package json |
| |
| import ( |
| "reflect" |
| "strconv" |
| |
| jsonv2 "encoding/json/v2" |
| ) |
| |
| // Marshal returns the JSON encoding of v. |
| // |
| // Marshal traverses the value v recursively. |
| // If an encountered value implements [Marshaler] |
| // and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON] |
| // to produce JSON. If no [Marshaler.MarshalJSON] method is present but the |
| // value implements [encoding.TextMarshaler] instead, Marshal calls |
| // [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string. |
| // The nil pointer exception is not strictly necessary |
| // but mimics a similar, necessary exception in the behavior of |
| // [Unmarshaler.UnmarshalJSON]. |
| // |
| // Otherwise, Marshal uses the following type-dependent default encodings: |
| // |
| // Boolean values encode as JSON booleans. |
| // |
| // Floating point, integer, and [Number] values encode as JSON numbers. |
| // NaN and +/-Inf values will return an [UnsupportedValueError]. |
| // |
| // String values encode as JSON strings coerced to valid UTF-8, |
| // replacing invalid bytes with the Unicode replacement rune. |
| // So that the JSON will be safe to embed inside HTML <script> tags, |
| // the string is encoded using [HTMLEscape], |
| // which replaces "<", ">", "&", U+2028, and U+2029 are escaped |
| // to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". |
| // This replacement can be disabled when using an [Encoder], |
| // by calling [Encoder.SetEscapeHTML](false). |
| // |
| // Array and slice values encode as JSON arrays, except that |
| // []byte encodes as a base64-encoded string, and a nil slice |
| // encodes as the null JSON value. |
| // |
| // Struct values encode as JSON objects. |
| // Each exported struct field becomes a member of the object, using the |
| // field name as the object key, unless the field is omitted for one of the |
| // reasons given below. |
| // |
| // The encoding of each struct field can be customized by the format string |
| // stored under the "json" key in the struct field's tag. |
| // The format string gives the name of the field, possibly followed by a |
| // comma-separated list of options. The name may be empty in order to |
| // specify options without overriding the default field name. |
| // |
| // The "omitempty" option specifies that the field should be omitted |
| // from the encoding if the field has an empty value, defined as |
| // false, 0, a nil pointer, a nil interface value, and any array, |
| // slice, map, or string of length zero. |
| // |
| // As a special case, if the field tag is "-", the field is always omitted. |
| // JSON names containing commas or quotes, or names identical to "" or "-", |
| // can be specified using a single-quoted string literal, where the syntax |
| // is identical to the Go grammar for a double-quoted string literal, |
| // but instead uses single quotes as the delimiters. |
| // |
| // Examples of struct field tags and their meanings: |
| // |
| // // Field appears in JSON as key "myName". |
| // Field int `json:"myName"` |
| // |
| // // Field appears in JSON as key "myName" and |
| // // the field is omitted from the object if its value is empty, |
| // // as defined above. |
| // Field int `json:"myName,omitempty"` |
| // |
| // // Field appears in JSON as key "Field" (the default), but |
| // // the field is skipped if empty. |
| // // Note the leading comma. |
| // Field int `json:",omitempty"` |
| // |
| // // Field is ignored by this package. |
| // Field int `json:"-"` |
| // |
| // // Field appears in JSON as key "-". |
| // Field int `json:"'-'"` |
| // |
| // The "omitzero" option specifies that the field should be omitted |
| // from the encoding if the field has a zero value, according to rules: |
| // |
| // 1) If the field type has an "IsZero() bool" method, that will be used to |
| // determine whether the value is zero. |
| // |
| // 2) Otherwise, the value is zero if it is the zero value for its type. |
| // |
| // If both "omitempty" and "omitzero" are specified, the field will be omitted |
| // if the value is either empty or zero (or both). |
| // |
| // The "string" option signals that a field is stored as JSON inside a |
| // JSON-encoded string. It applies only to fields of string, floating point, |
| // integer, or boolean types. This extra level of encoding is sometimes used |
| // when communicating with JavaScript programs: |
| // |
| // Int64String int64 `json:",string"` |
| // |
| // The key name will be used if it's a non-empty string consisting of |
| // only Unicode letters, digits, and ASCII punctuation except quotation |
| // marks, backslash, and comma. |
| // |
| // Embedded struct fields are usually marshaled as if their inner exported fields |
| // were fields in the outer struct, subject to the usual Go visibility rules amended |
| // as described in the next paragraph. |
| // An anonymous struct field with a name given in its JSON tag is treated as |
| // having that name, rather than being anonymous. |
| // An anonymous struct field of interface type is treated the same as having |
| // that type as its name, rather than being anonymous. |
| // |
| // The Go visibility rules for struct fields are amended for JSON when |
| // deciding which field to marshal or unmarshal. If there are |
| // multiple fields at the same level, and that level is the least |
| // nested (and would therefore be the nesting level selected by the |
| // usual Go rules), the following extra rules apply: |
| // |
| // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, |
| // even if there are multiple untagged fields that would otherwise conflict. |
| // |
| // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. |
| // |
| // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. |
| // |
| // Handling of anonymous struct fields is new in Go 1.1. |
| // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of |
| // an anonymous struct field in both current and earlier versions, give the field |
| // a JSON tag of "-". |
| // |
| // Map values encode as JSON objects. The map's key type must either be a |
| // string, an integer type, or implement [encoding.TextMarshaler]. The map keys |
| // are sorted and used as JSON object keys by applying the following rules, |
| // subject to the UTF-8 coercion described for string values above: |
| // - keys of any string type are used directly |
| // - keys that implement [encoding.TextMarshaler] are marshaled |
| // - integer keys are converted to strings |
| // |
| // Pointer values encode as the value pointed to. |
| // A nil pointer encodes as the null JSON value. |
| // |
| // Interface values encode as the value contained in the interface. |
| // A nil interface value encodes as the null JSON value. |
| // |
| // Channel, complex, and function values cannot be encoded in JSON. |
| // Attempting to encode such a value causes Marshal to return |
| // an [UnsupportedTypeError]. |
| // |
| // JSON cannot represent cyclic data structures and Marshal does not |
| // handle them. Passing cyclic structures to Marshal will result in |
| // an error. |
| func Marshal(v any) ([]byte, error) { |
| return jsonv2.Marshal(v, DefaultOptionsV1()) |
| } |
| |
| // MarshalIndent is like [Marshal] but applies [Indent] to format the output. |
| // Each JSON element in the output will begin on a new line beginning with prefix |
| // followed by one or more copies of indent according to the indentation nesting. |
| func MarshalIndent(v any, prefix, indent string) ([]byte, error) { |
| b, err := Marshal(v) |
| if err != nil { |
| return nil, err |
| } |
| b, err = appendIndent(nil, b, prefix, indent) |
| if err != nil { |
| return nil, err |
| } |
| return b, nil |
| } |
| |
| // Marshaler is the interface implemented by types that |
| // can marshal themselves into valid JSON. |
| type Marshaler = jsonv2.Marshaler |
| |
| // An UnsupportedTypeError is returned by [Marshal] when attempting |
| // to encode an unsupported value type. |
| type UnsupportedTypeError struct { |
| Type reflect.Type |
| } |
| |
| func (e *UnsupportedTypeError) Error() string { |
| return "json: unsupported type: " + e.Type.String() |
| } |
| |
| // An UnsupportedValueError is returned by [Marshal] when attempting |
| // to encode an unsupported value. |
| type UnsupportedValueError struct { |
| Value reflect.Value |
| Str string |
| } |
| |
| func (e *UnsupportedValueError) Error() string { |
| return "json: unsupported value: " + e.Str |
| } |
| |
| // Before Go 1.2, an InvalidUTF8Error was returned by [Marshal] when |
| // attempting to encode a string value with invalid UTF-8 sequences. |
| // As of Go 1.2, [Marshal] instead coerces the string to valid UTF-8 by |
| // replacing invalid bytes with the Unicode replacement rune U+FFFD. |
| // |
| // Deprecated: No longer used; kept for compatibility. |
| type InvalidUTF8Error struct { |
| S string // the whole string value that caused the error |
| } |
| |
| func (e *InvalidUTF8Error) Error() string { |
| return "json: invalid UTF-8 in string: " + strconv.Quote(e.S) |
| } |
| |
| // A MarshalerError represents an error from calling a |
| // [Marshaler.MarshalJSON] or [encoding.TextMarshaler.MarshalText] method. |
| type MarshalerError struct { |
| Type reflect.Type |
| Err error |
| sourceFunc string |
| } |
| |
| func (e *MarshalerError) Error() string { |
| srcFunc := e.sourceFunc |
| if srcFunc == "" { |
| srcFunc = "MarshalJSON" |
| } |
| return "json: error calling " + srcFunc + |
| " for type " + e.Type.String() + |
| ": " + e.Err.Error() |
| } |
| |
| // Unwrap returns the underlying error. |
| func (e *MarshalerError) Unwrap() error { return e.Err } |