github.com/night-codes/go-json@v0.9.15/json.go (about) 1 package json 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 8 "github.com/night-codes/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{}) ([]byte, error) { 170 return MarshalWithOption(v) 171 } 172 173 // MarshalNoEscape returns the JSON encoding of v and doesn't escape v. 174 func MarshalNoEscape(v interface{}) ([]byte, error) { 175 return marshalNoEscape(v) 176 } 177 178 // MarshalContext returns the JSON encoding of v with context.Context and EncodeOption. 179 func MarshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { 180 return marshalContext(ctx, v, optFuncs...) 181 } 182 183 // MarshalWithOption returns the JSON encoding of v with EncodeOption. 184 func MarshalWithOption(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { 185 return marshal(v, optFuncs...) 186 } 187 188 // MarshalIndent is like Marshal but applies Indent to format the output. 189 // Each JSON element in the output will begin on a new line beginning with prefix 190 // followed by one or more copies of indent according to the indentation nesting. 191 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { 192 return MarshalIndentWithOption(v, prefix, indent) 193 } 194 195 // MarshalIndentWithOption is like Marshal but applies Indent to format the output with EncodeOption. 196 func MarshalIndentWithOption(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) { 197 return marshalIndent(v, prefix, indent, optFuncs...) 198 } 199 200 // Unmarshal parses the JSON-encoded data and stores the result 201 // in the value pointed to by v. If v is nil or not a pointer, 202 // Unmarshal returns an InvalidUnmarshalError. 203 // 204 // Unmarshal uses the inverse of the encodings that 205 // Marshal uses, allocating maps, slices, and pointers as necessary, 206 // with the following additional rules: 207 // 208 // To unmarshal JSON into a pointer, Unmarshal first handles the case of 209 // the JSON being the JSON literal null. In that case, Unmarshal sets 210 // the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into 211 // the value pointed at by the pointer. If the pointer is nil, Unmarshal 212 // allocates a new value for it to point to. 213 // 214 // To unmarshal JSON into a value implementing the Unmarshaler interface, 215 // Unmarshal calls that value's UnmarshalJSON method, including 216 // when the input is a JSON null. 217 // Otherwise, if the value implements encoding.TextUnmarshaler 218 // and the input is a JSON quoted string, Unmarshal calls that value's 219 // UnmarshalText method with the unquoted form of the string. 220 // 221 // To unmarshal JSON into a struct, Unmarshal matches incoming object 222 // keys to the keys used by Marshal (either the struct field name or its tag), 223 // preferring an exact match but also accepting a case-insensitive match. By 224 // default, object keys which don't have a corresponding struct field are 225 // ignored (see Decoder.DisallowUnknownFields for an alternative). 226 // 227 // To unmarshal JSON into an interface value, 228 // Unmarshal stores one of these in the interface value: 229 // 230 // bool, for JSON booleans 231 // float64, for JSON numbers 232 // string, for JSON strings 233 // []interface{}, for JSON arrays 234 // map[string]interface{}, for JSON objects 235 // nil for JSON null 236 // 237 // To unmarshal a JSON array into a slice, Unmarshal resets the slice length 238 // to zero and then appends each element to the slice. 239 // As a special case, to unmarshal an empty JSON array into a slice, 240 // Unmarshal replaces the slice with a new empty slice. 241 // 242 // To unmarshal a JSON array into a Go array, Unmarshal decodes 243 // JSON array elements into corresponding Go array elements. 244 // If the Go array is smaller than the JSON array, 245 // the additional JSON array elements are discarded. 246 // If the JSON array is smaller than the Go array, 247 // the additional Go array elements are set to zero values. 248 // 249 // To unmarshal a JSON object into a map, Unmarshal first establishes a map to 250 // use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal 251 // reuses the existing map, keeping existing entries. Unmarshal then stores 252 // key-value pairs from the JSON object into the map. The map's key type must 253 // either be any string type, an integer, implement json.Unmarshaler, or 254 // implement encoding.TextUnmarshaler. 255 // 256 // If a JSON value is not appropriate for a given target type, 257 // or if a JSON number overflows the target type, Unmarshal 258 // skips that field and completes the unmarshaling as best it can. 259 // If no more serious errors are encountered, Unmarshal returns 260 // an UnmarshalTypeError describing the earliest such error. In any 261 // case, it's not guaranteed that all the remaining fields following 262 // the problematic one will be unmarshaled into the target object. 263 // 264 // The JSON null value unmarshals into an interface, map, pointer, or slice 265 // by setting that Go value to nil. Because null is often used in JSON to mean 266 // “not present,” unmarshaling a JSON null into any other Go type has no effect 267 // on the value and produces no error. 268 // 269 // When unmarshaling quoted strings, invalid UTF-8 or 270 // invalid UTF-16 surrogate pairs are not treated as an error. 271 // Instead, they are replaced by the Unicode replacement 272 // character U+FFFD. 273 func Unmarshal(data []byte, v interface{}) error { 274 return unmarshal(data, v) 275 } 276 277 // UnmarshalContext parses the JSON-encoded data and stores the result 278 // in the value pointed to by v. If you implement the UnmarshalerContext interface, 279 // call it with ctx as an argument. 280 func UnmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { 281 return unmarshalContext(ctx, data, v) 282 } 283 284 func UnmarshalWithOption(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { 285 return unmarshal(data, v, optFuncs...) 286 } 287 288 func UnmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { 289 return unmarshalNoEscape(data, v, optFuncs...) 290 } 291 292 // A Token holds a value of one of these types: 293 // 294 // Delim, for the four JSON delimiters [ ] { } 295 // bool, for JSON booleans 296 // float64, for JSON numbers 297 // Number, for JSON numbers 298 // string, for JSON string literals 299 // nil, for JSON null 300 type Token = json.Token 301 302 // A Number represents a JSON number literal. 303 type Number = json.Number 304 305 // RawMessage is a raw encoded JSON value. 306 // It implements Marshaler and Unmarshaler and can 307 // be used to delay JSON decoding or precompute a JSON encoding. 308 type RawMessage = json.RawMessage 309 310 // A Delim is a JSON array or object delimiter, one of [ ] { or }. 311 type Delim = json.Delim 312 313 // Compact appends to dst the JSON-encoded src with 314 // insignificant space characters elided. 315 func Compact(dst *bytes.Buffer, src []byte) error { 316 return encoder.Compact(dst, src, false) 317 } 318 319 // Indent appends to dst an indented form of the JSON-encoded src. 320 // Each element in a JSON object or array begins on a new, 321 // indented line beginning with prefix followed by one or more 322 // copies of indent according to the indentation nesting. 323 // The data appended to dst does not begin with the prefix nor 324 // any indentation, to make it easier to embed inside other formatted JSON data. 325 // Although leading space characters (space, tab, carriage return, newline) 326 // at the beginning of src are dropped, trailing space characters 327 // at the end of src are preserved and copied to dst. 328 // For example, if src has no trailing spaces, neither will dst; 329 // if src ends in a trailing newline, so will dst. 330 func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error { 331 return encoder.Indent(dst, src, prefix, indent) 332 } 333 334 // HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 335 // characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 336 // so that the JSON will be safe to embed inside HTML <script> tags. 337 // For historical reasons, web browsers don't honor standard HTML 338 // escaping within <script> tags, so an alternative JSON encoding must 339 // be used. 340 func HTMLEscape(dst *bytes.Buffer, src []byte) { 341 var v interface{} 342 dec := NewDecoder(bytes.NewBuffer(src)) 343 dec.UseNumber() 344 if err := dec.Decode(&v); err != nil { 345 return 346 } 347 buf, _ := marshal(v) 348 dst.Write(buf) 349 } 350 351 // Valid reports whether data is a valid JSON encoding. 352 func Valid(data []byte) bool { 353 var v interface{} 354 decoder := NewDecoder(bytes.NewReader(data)) 355 err := decoder.Decode(&v) 356 if err != nil { 357 return false 358 } 359 if !decoder.More() { 360 return true 361 } 362 return decoder.InputOffset() >= int64(len(data)) 363 } 364 365 func init() { 366 encoder.Marshal = Marshal 367 encoder.Unmarshal = Unmarshal 368 }