gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

json.go (15278B)


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