Source file src/encoding/json/v2_encode.go
1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build goexperiment.jsonv2 6 7 // Package json implements encoding and decoding of JSON as defined in 8 // RFC 7159. The mapping between JSON and Go values is described 9 // in the documentation for the Marshal and Unmarshal functions. 10 // 11 // See "JSON and Go" for an introduction to this package: 12 // https://golang.org/doc/articles/json_and_go.html 13 package json 14 15 import ( 16 "reflect" 17 "strconv" 18 19 jsonv2 "encoding/json/v2" 20 ) 21 22 // Marshal returns the JSON encoding of v. 23 // 24 // Marshal traverses the value v recursively. 25 // If an encountered value implements [Marshaler] 26 // and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON] 27 // to produce JSON. If no [Marshaler.MarshalJSON] method is present but the 28 // value implements [encoding.TextMarshaler] instead, Marshal calls 29 // [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string. 30 // The nil pointer exception is not strictly necessary 31 // but mimics a similar, necessary exception in the behavior of 32 // [Unmarshaler.UnmarshalJSON]. 33 // 34 // Otherwise, Marshal uses the following type-dependent default encodings: 35 // 36 // Boolean values encode as JSON booleans. 37 // 38 // Floating point, integer, and [Number] values encode as JSON numbers. 39 // NaN and +/-Inf values will return an [UnsupportedValueError]. 40 // 41 // String values encode as JSON strings coerced to valid UTF-8, 42 // replacing invalid bytes with the Unicode replacement rune. 43 // So that the JSON will be safe to embed inside HTML <script> tags, 44 // the string is encoded using [HTMLEscape], 45 // which replaces "<", ">", "&", U+2028, and U+2029 are escaped 46 // to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". 47 // This replacement can be disabled when using an [Encoder], 48 // by calling [Encoder.SetEscapeHTML](false). 49 // 50 // Array and slice values encode as JSON arrays, except that 51 // []byte encodes as a base64-encoded string, and a nil slice 52 // encodes as the null JSON value. 53 // 54 // Struct values encode as JSON objects. 55 // Each exported struct field becomes a member of the object, using the 56 // field name as the object key, unless the field is omitted for one of the 57 // reasons given below. 58 // 59 // The encoding of each struct field can be customized by the format string 60 // stored under the "json" key in the struct field's tag. 61 // The format string gives the name of the field, possibly followed by a 62 // comma-separated list of options. The name may be empty in order to 63 // specify options without overriding the default field name. 64 // 65 // The "omitempty" option specifies that the field should be omitted 66 // from the encoding if the field has an empty value, defined as 67 // false, 0, a nil pointer, a nil interface value, and any array, 68 // slice, map, or string of length zero. 69 // 70 // As a special case, if the field tag is "-", the field is always omitted. 71 // JSON names containing commas or quotes, or names identical to "" or "-", 72 // can be specified using a single-quoted string literal, where the syntax 73 // is identical to the Go grammar for a double-quoted string literal, 74 // but instead uses single quotes as the delimiters. 75 // 76 // Examples of struct field tags and their meanings: 77 // 78 // // Field appears in JSON as key "myName". 79 // Field int `json:"myName"` 80 // 81 // // Field appears in JSON as key "myName" and 82 // // the field is omitted from the object if its value is empty, 83 // // as defined above. 84 // Field int `json:"myName,omitempty"` 85 // 86 // // Field appears in JSON as key "Field" (the default), but 87 // // the field is skipped if empty. 88 // // Note the leading comma. 89 // Field int `json:",omitempty"` 90 // 91 // // Field is ignored by this package. 92 // Field int `json:"-"` 93 // 94 // // Field appears in JSON as key "-". 95 // Field int `json:"'-'"` 96 // 97 // The "omitzero" option specifies that the field should be omitted 98 // from the encoding if the field has a zero value, according to rules: 99 // 100 // 1) If the field type has an "IsZero() bool" method, that will be used to 101 // determine whether the value is zero. 102 // 103 // 2) Otherwise, the value is zero if it is the zero value for its type. 104 // 105 // If both "omitempty" and "omitzero" are specified, the field will be omitted 106 // if the value is either empty or zero (or both). 107 // 108 // The "string" option signals that a field is stored as JSON inside a 109 // JSON-encoded string. It applies only to fields of string, floating point, 110 // integer, or boolean types. This extra level of encoding is sometimes used 111 // when communicating with JavaScript programs: 112 // 113 // Int64String int64 `json:",string"` 114 // 115 // The key name will be used if it's a non-empty string consisting of 116 // only Unicode letters, digits, and ASCII punctuation except quotation 117 // marks, backslash, and comma. 118 // 119 // Embedded struct fields are usually marshaled as if their inner exported fields 120 // were fields in the outer struct, subject to the usual Go visibility rules amended 121 // as described in the next paragraph. 122 // An anonymous struct field with a name given in its JSON tag is treated as 123 // having that name, rather than being anonymous. 124 // An anonymous struct field of interface type is treated the same as having 125 // that type as its name, rather than being anonymous. 126 // 127 // The Go visibility rules for struct fields are amended for JSON when 128 // deciding which field to marshal or unmarshal. If there are 129 // multiple fields at the same level, and that level is the least 130 // nested (and would therefore be the nesting level selected by the 131 // usual Go rules), the following extra rules apply: 132 // 133 // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, 134 // even if there are multiple untagged fields that would otherwise conflict. 135 // 136 // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 137 // 138 // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. 139 // 140 // Handling of anonymous struct fields is new in Go 1.1. 141 // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of 142 // an anonymous struct field in both current and earlier versions, give the field 143 // a JSON tag of "-". 144 // 145 // Map values encode as JSON objects. The map's key type must either be a 146 // string, an integer type, or implement [encoding.TextMarshaler]. The map keys 147 // are sorted and used as JSON object keys by applying the following rules, 148 // subject to the UTF-8 coercion described for string values above: 149 // - keys of any string type are used directly 150 // - keys that implement [encoding.TextMarshaler] are marshaled 151 // - integer keys are converted to strings 152 // 153 // Pointer values encode as the value pointed to. 154 // A nil pointer encodes as the null JSON value. 155 // 156 // Interface values encode as the value contained in the interface. 157 // A nil interface value encodes as the null JSON value. 158 // 159 // Channel, complex, and function values cannot be encoded in JSON. 160 // Attempting to encode such a value causes Marshal to return 161 // an [UnsupportedTypeError]. 162 // 163 // JSON cannot represent cyclic data structures and Marshal does not 164 // handle them. Passing cyclic structures to Marshal will result in 165 // an error. 166 func Marshal(v any) ([]byte, error) { 167 return jsonv2.Marshal(v, DefaultOptionsV1()) 168 } 169 170 // MarshalIndent is like [Marshal] but applies [Indent] to format the output. 171 // Each JSON element in the output will begin on a new line beginning with prefix 172 // followed by one or more copies of indent according to the indentation nesting. 173 func MarshalIndent(v any, prefix, indent string) ([]byte, error) { 174 b, err := Marshal(v) 175 if err != nil { 176 return nil, err 177 } 178 b, err = appendIndent(nil, b, prefix, indent) 179 if err != nil { 180 return nil, err 181 } 182 return b, nil 183 } 184 185 // Marshaler is the interface implemented by types that 186 // can marshal themselves into valid JSON. 187 type Marshaler = jsonv2.Marshaler 188 189 // An UnsupportedTypeError is returned by [Marshal] when attempting 190 // to encode an unsupported value type. 191 type UnsupportedTypeError struct { 192 Type reflect.Type 193 } 194 195 func (e *UnsupportedTypeError) Error() string { 196 return "json: unsupported type: " + e.Type.String() 197 } 198 199 // An UnsupportedValueError is returned by [Marshal] when attempting 200 // to encode an unsupported value. 201 type UnsupportedValueError struct { 202 Value reflect.Value 203 Str string 204 } 205 206 func (e *UnsupportedValueError) Error() string { 207 return "json: unsupported value: " + e.Str 208 } 209 210 // Before Go 1.2, an InvalidUTF8Error was returned by [Marshal] when 211 // attempting to encode a string value with invalid UTF-8 sequences. 212 // As of Go 1.2, [Marshal] instead coerces the string to valid UTF-8 by 213 // replacing invalid bytes with the Unicode replacement rune U+FFFD. 214 // 215 // Deprecated: No longer used; kept for compatibility. 216 type InvalidUTF8Error struct { 217 S string // the whole string value that caused the error 218 } 219 220 func (e *InvalidUTF8Error) Error() string { 221 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S) 222 } 223 224 // A MarshalerError represents an error from calling a 225 // [Marshaler.MarshalJSON] or [encoding.TextMarshaler.MarshalText] method. 226 type MarshalerError struct { 227 Type reflect.Type 228 Err error 229 sourceFunc string 230 } 231 232 func (e *MarshalerError) Error() string { 233 srcFunc := e.sourceFunc 234 if srcFunc == "" { 235 srcFunc = "MarshalJSON" 236 } 237 return "json: error calling " + srcFunc + 238 " for type " + e.Type.String() + 239 ": " + e.Err.Error() 240 } 241 242 // Unwrap returns the underlying error. 243 func (e *MarshalerError) Unwrap() error { return e.Err } 244