Update
This commit is contained in:
2
vendor/github.com/go-json-experiment/json/README.md
generated
vendored
2
vendor/github.com/go-json-experiment/json/README.md
generated
vendored
@@ -159,7 +159,7 @@ This table shows an overview of the changes:
|
||||
| When unmarshaling, **an error does not occur** if the input JSON value contains objects with duplicate names. | When unmarshaling, **an error does occur** if the input JSON value contains objects with duplicate names. | [DuplicateNames](/v1/diff_test.go#:~:text=TestDuplicateNames) |
|
||||
| Unmarshaling a JSON null into a non-empty Go value **inconsistently clears the value or does nothing**. | Unmarshaling a JSON null into a non-empty Go value **always clears the value**. | [MergeNull](/v1/diff_test.go#:~:text=TestMergeNull) |
|
||||
| Unmarshaling a JSON value into a non-empty Go value **follows inconsistent and bizarre behavior**. | Unmarshaling a JSON value into a non-empty Go value **always merges if the input is an object, and otherwise replaces**. | [MergeComposite](/v1/diff_test.go#:~:text=TestMergeComposite) |
|
||||
| A `time.Duration` is represented as a **JSON number containing the decimal number of nanoseconds**. | A `time.Duration` is represented as a **JSON string containing the formatted duration (e.g., "1h2m3.456s")**. | [TimeDurations](/v1/diff_test.go#:~:text=TestTimeDurations) |
|
||||
| A `time.Duration` is represented as a **JSON number containing the decimal number of nanoseconds**. | A `time.Duration` has no default representation in v2 (see [#71631](https://golang.org/issue/71631)) and results in an error. | |
|
||||
| A Go struct with only unexported fields **can be serialized**. | A Go struct with only unexported fields **cannot be serialized**. | [EmptyStructs](/v1/diff_test.go#:~:text=TestEmptyStructs) |
|
||||
|
||||
See [diff_test.go](/v1/diff_test.go) for details about every change.
|
||||
|
||||
985
vendor/github.com/go-json-experiment/json/alias.go
generated
vendored
Normal file
985
vendor/github.com/go-json-experiment/json/alias.go
generated
vendored
Normal file
@@ -0,0 +1,985 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
// Code generated by alias_gen.go; DO NOT EDIT.
|
||||
|
||||
//go:build goexperiment.jsonv2 && go1.25
|
||||
|
||||
// Package json implements semantic processing of JSON as specified in RFC 8259.
|
||||
// JSON is a simple data interchange format that can represent
|
||||
// primitive data types such as booleans, strings, and numbers,
|
||||
// in addition to structured data types such as objects and arrays.
|
||||
//
|
||||
// [Marshal] and [Unmarshal] encode and decode Go values
|
||||
// to/from JSON text contained within a []byte.
|
||||
// [MarshalWrite] and [UnmarshalRead] operate on JSON text
|
||||
// by writing to or reading from an [io.Writer] or [io.Reader].
|
||||
// [MarshalEncode] and [UnmarshalDecode] operate on JSON text
|
||||
// by encoding to or decoding from a [jsontext.Encoder] or [jsontext.Decoder].
|
||||
// [Options] may be passed to each of the marshal or unmarshal functions
|
||||
// to configure the semantic behavior of marshaling and unmarshaling
|
||||
// (i.e., alter how JSON data is understood as Go data and vice versa).
|
||||
// [jsontext.Options] may also be passed to the marshal or unmarshal functions
|
||||
// to configure the syntactic behavior of encoding or decoding.
|
||||
//
|
||||
// The data types of JSON are mapped to/from the data types of Go based on
|
||||
// the closest logical equivalent between the two type systems. For example,
|
||||
// a JSON boolean corresponds with a Go bool,
|
||||
// a JSON string corresponds with a Go string,
|
||||
// a JSON number corresponds with a Go int, uint or float,
|
||||
// a JSON array corresponds with a Go slice or array, and
|
||||
// a JSON object corresponds with a Go struct or map.
|
||||
// See the documentation on [Marshal] and [Unmarshal] for a comprehensive list
|
||||
// of how the JSON and Go type systems correspond.
|
||||
//
|
||||
// Arbitrary Go types can customize their JSON representation by implementing
|
||||
// [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom].
|
||||
// This provides authors of Go types with control over how their types are
|
||||
// serialized as JSON. Alternatively, users can implement functions that match
|
||||
// [MarshalFunc], [MarshalToFunc], [UnmarshalFunc], or [UnmarshalFromFunc]
|
||||
// to specify the JSON representation for arbitrary types.
|
||||
// This provides callers of JSON functionality with control over
|
||||
// how any arbitrary type is serialized as JSON.
|
||||
//
|
||||
// # JSON Representation of Go structs
|
||||
//
|
||||
// A Go struct is naturally represented as a JSON object,
|
||||
// where each Go struct field corresponds with a JSON object member.
|
||||
// When marshaling, all Go struct fields are recursively encoded in depth-first
|
||||
// order as JSON object members except those that are ignored or omitted.
|
||||
// When unmarshaling, JSON object members are recursively decoded
|
||||
// into the corresponding Go struct fields.
|
||||
// Object members that do not match any struct fields,
|
||||
// also known as “unknown members”, are ignored by default or rejected
|
||||
// if [RejectUnknownMembers] is specified.
|
||||
//
|
||||
// The representation of each struct field can be customized in the
|
||||
// "json" struct field tag, where the tag is a comma separated list of options.
|
||||
// As a special case, if the entire tag is `json:"-"`,
|
||||
// then the field is ignored with regard to its JSON representation.
|
||||
// Some options also have equivalent behavior controlled by a caller-specified [Options].
|
||||
// Field-specified options take precedence over caller-specified options.
|
||||
//
|
||||
// The first option is the JSON object name override for the Go struct field.
|
||||
// If the name is not specified, then the Go struct field name
|
||||
// is used as the JSON object name. 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.
|
||||
// By default, unmarshaling uses case-sensitive matching to identify
|
||||
// the Go struct field associated with a JSON object name.
|
||||
//
|
||||
// After the name, the following tag options are supported:
|
||||
//
|
||||
// - omitzero: When marshaling, the "omitzero" option specifies that
|
||||
// the struct field should be omitted if the field value is zero
|
||||
// as determined by the "IsZero() bool" method if present,
|
||||
// otherwise based on whether the field is the zero Go value.
|
||||
// This option has no effect when unmarshaling.
|
||||
//
|
||||
// - omitempty: When marshaling, the "omitempty" option specifies that
|
||||
// the struct field should be omitted if the field value would have been
|
||||
// encoded as a JSON null, empty string, empty object, or empty array.
|
||||
// This option has no effect when unmarshaling.
|
||||
//
|
||||
// - string: The "string" option specifies that [StringifyNumbers]
|
||||
// be set when marshaling or unmarshaling a struct field value.
|
||||
// This causes numeric types to be encoded as a JSON number
|
||||
// within a JSON string, and to be decoded from a JSON string
|
||||
// containing the JSON number without any surrounding whitespace.
|
||||
// This extra level of encoding is often necessary since
|
||||
// many JSON parsers cannot precisely represent 64-bit integers.
|
||||
//
|
||||
// - case: When unmarshaling, the "case" option specifies how
|
||||
// JSON object names are matched with the JSON name for Go struct fields.
|
||||
// The option is a key-value pair specified as "case:value" where
|
||||
// the value must either be 'ignore' or 'strict'.
|
||||
// The 'ignore' value specifies that matching is case-insensitive
|
||||
// where dashes and underscores are also ignored. If multiple fields match,
|
||||
// the first declared field in breadth-first order takes precedence.
|
||||
// The 'strict' value specifies that matching is case-sensitive.
|
||||
// This takes precedence over the [MatchCaseInsensitiveNames] option.
|
||||
//
|
||||
// - inline: The "inline" option specifies that
|
||||
// the JSON representable content of this field type is to be promoted
|
||||
// as if they were specified in the parent struct.
|
||||
// It is the JSON equivalent of Go struct embedding.
|
||||
// A Go embedded field is implicitly inlined unless an explicit JSON name
|
||||
// is specified. The inlined field must be a Go struct
|
||||
// (that does not implement any JSON methods), [jsontext.Value],
|
||||
// map[~string]T, or an unnamed pointer to such types. When marshaling,
|
||||
// inlined fields from a pointer type are omitted if it is nil.
|
||||
// Inlined fields of type [jsontext.Value] and map[~string]T are called
|
||||
// “inlined fallbacks” as they can represent all possible
|
||||
// JSON object members not directly handled by the parent struct.
|
||||
// Only one inlined fallback field may be specified in a struct,
|
||||
// while many non-fallback fields may be specified. This option
|
||||
// must not be specified with any other option (including the JSON name).
|
||||
//
|
||||
// - unknown: The "unknown" option is a specialized variant
|
||||
// of the inlined fallback to indicate that this Go struct field
|
||||
// contains any number of unknown JSON object members. The field type must
|
||||
// be a [jsontext.Value], map[~string]T, or an unnamed pointer to such types.
|
||||
// If [DiscardUnknownMembers] is specified when marshaling,
|
||||
// the contents of this field are ignored.
|
||||
// If [RejectUnknownMembers] is specified when unmarshaling,
|
||||
// any unknown object members are rejected regardless of whether
|
||||
// an inlined fallback with the "unknown" option exists. This option
|
||||
// must not be specified with any other option (including the JSON name).
|
||||
//
|
||||
// - format: The "format" option specifies a format flag
|
||||
// used to specialize the formatting of the field value.
|
||||
// The option is a key-value pair specified as "format:value" where
|
||||
// the value must be either a literal consisting of letters and numbers
|
||||
// (e.g., "format:RFC3339") or a single-quoted string literal
|
||||
// (e.g., "format:'2006-01-02'"). The interpretation of the format flag
|
||||
// is determined by the struct field type.
|
||||
//
|
||||
// The "omitzero" and "omitempty" options are mostly semantically identical.
|
||||
// The former is defined in terms of the Go type system,
|
||||
// while the latter in terms of the JSON type system.
|
||||
// Consequently they behave differently in some circumstances.
|
||||
// For example, only a nil slice or map is omitted under "omitzero", while
|
||||
// an empty slice or map is omitted under "omitempty" regardless of nilness.
|
||||
// The "omitzero" option is useful for types with a well-defined zero value
|
||||
// (e.g., [net/netip.Addr]) or have an IsZero method (e.g., [time.Time.IsZero]).
|
||||
//
|
||||
// Every Go struct corresponds to a list of JSON representable fields
|
||||
// which is constructed by performing a breadth-first search over
|
||||
// all struct fields (excluding unexported or ignored fields),
|
||||
// where the search recursively descends into inlined structs.
|
||||
// The set of non-inlined fields in a struct must have unique JSON names.
|
||||
// If multiple fields all have the same JSON name, then the one
|
||||
// at shallowest depth takes precedence and the other fields at deeper depths
|
||||
// are excluded from the list of JSON representable fields.
|
||||
// If multiple fields at the shallowest depth have the same JSON name,
|
||||
// but exactly one is explicitly tagged with a JSON name,
|
||||
// then that field takes precedence and all others are excluded from the list.
|
||||
// This is analogous to Go visibility rules for struct field selection
|
||||
// with embedded struct types.
|
||||
//
|
||||
// Marshaling or unmarshaling a non-empty struct
|
||||
// without any JSON representable fields results in a [SemanticError].
|
||||
// Unexported fields must not have any `json` tags except for `json:"-"`.
|
||||
//
|
||||
// # Security Considerations
|
||||
//
|
||||
// JSON is frequently used as a data interchange format to communicate
|
||||
// between different systems, possibly implemented in different languages.
|
||||
// For interoperability and security reasons, it is important that
|
||||
// all implementations agree upon the semantic meaning of the data.
|
||||
//
|
||||
// [For example, suppose we have two micro-services.]
|
||||
// The first service is responsible for authenticating a JSON request,
|
||||
// while the second service is responsible for executing the request
|
||||
// (having assumed that the prior service authenticated the request).
|
||||
// If an attacker were able to maliciously craft a JSON request such that
|
||||
// both services believe that the same request is from different users,
|
||||
// it could bypass the authenticator with valid credentials for one user,
|
||||
// but maliciously perform an action on behalf of a different user.
|
||||
//
|
||||
// According to RFC 8259, there unfortunately exist many JSON texts
|
||||
// that are syntactically valid but semantically ambiguous.
|
||||
// For example, the standard does not define how to interpret duplicate
|
||||
// names within an object.
|
||||
//
|
||||
// The v1 [encoding/json] and [encoding/json/v2] packages
|
||||
// interpret some inputs in different ways. In particular:
|
||||
//
|
||||
// - The standard specifies that JSON must be encoded using UTF-8.
|
||||
// By default, v1 replaces invalid bytes of UTF-8 in JSON strings
|
||||
// with the Unicode replacement character,
|
||||
// while v2 rejects inputs with invalid UTF-8.
|
||||
// To change the default, specify the [jsontext.AllowInvalidUTF8] option.
|
||||
// The replacement of invalid UTF-8 is a form of data corruption
|
||||
// that alters the precise meaning of strings.
|
||||
//
|
||||
// - The standard does not specify a particular behavior when
|
||||
// duplicate names are encountered within a JSON object,
|
||||
// which means that different implementations may behave differently.
|
||||
// By default, v1 allows for the presence of duplicate names,
|
||||
// while v2 rejects duplicate names.
|
||||
// To change the default, specify the [jsontext.AllowDuplicateNames] option.
|
||||
// If allowed, object members are processed in the order they are observed,
|
||||
// meaning that later values will replace or be merged into prior values,
|
||||
// depending on the Go value type.
|
||||
//
|
||||
// - The standard defines a JSON object as an unordered collection of name/value pairs.
|
||||
// While ordering can be observed through the underlying [jsontext] API,
|
||||
// both v1 and v2 generally avoid exposing the ordering.
|
||||
// No application should semantically depend on the order of object members.
|
||||
// Allowing duplicate names is a vector through which ordering of members
|
||||
// can accidentally be observed and depended upon.
|
||||
//
|
||||
// - The standard suggests that JSON object names are typically compared
|
||||
// based on equality of the sequence of Unicode code points,
|
||||
// which implies that comparing names is often case-sensitive.
|
||||
// When unmarshaling a JSON object into a Go struct,
|
||||
// by default, v1 uses a (loose) case-insensitive match on the name,
|
||||
// while v2 uses a (strict) case-sensitive match on the name.
|
||||
// To change the default, specify the [MatchCaseInsensitiveNames] option.
|
||||
// The use of case-insensitive matching provides another vector through
|
||||
// which duplicate names can occur. Allowing case-insensitive matching
|
||||
// means that v1 or v2 might interpret JSON objects differently from most
|
||||
// other JSON implementations (which typically use a case-sensitive match).
|
||||
//
|
||||
// - The standard does not specify a particular behavior when
|
||||
// an unknown name in a JSON object is encountered.
|
||||
// When unmarshaling a JSON object into a Go struct, by default
|
||||
// both v1 and v2 ignore unknown names and their corresponding values.
|
||||
// To change the default, specify the [RejectUnknownMembers] option.
|
||||
//
|
||||
// - The standard suggests that implementations may use a float64
|
||||
// to represent a JSON number. Consequently, large JSON integers
|
||||
// may lose precision when stored as a floating-point type.
|
||||
// Both v1 and v2 correctly preserve precision when marshaling and
|
||||
// unmarshaling a concrete integer type. However, even if v1 and v2
|
||||
// preserve precision for concrete types, other JSON implementations
|
||||
// may not be able to preserve precision for outputs produced by v1 or v2.
|
||||
// The `string` tag option can be used to specify that an integer type
|
||||
// is to be quoted within a JSON string to avoid loss of precision.
|
||||
// Furthermore, v1 and v2 may still lose precision when unmarshaling
|
||||
// into an any interface value, where unmarshal uses a float64
|
||||
// by default to represent a JSON number.
|
||||
// To change the default, specify the [WithUnmarshalers] option
|
||||
// with a custom unmarshaler that pre-populates the interface value
|
||||
// with a concrete Go type that can preserve precision.
|
||||
//
|
||||
// RFC 8785 specifies a canonical form for any JSON text,
|
||||
// which explicitly defines specific behaviors that RFC 8259 leaves undefined.
|
||||
// In theory, if a text can successfully [jsontext.Value.Canonicalize]
|
||||
// without changing the semantic meaning of the data, then it provides a
|
||||
// greater degree of confidence that the data is more secure and interoperable.
|
||||
//
|
||||
// The v2 API generally chooses more secure defaults than v1,
|
||||
// but care should still be taken with large integers or unknown members.
|
||||
//
|
||||
// [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json/jsontext"
|
||||
"encoding/json/v2"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Marshal serializes a Go value as a []byte according to the provided
|
||||
// marshal and encode options (while ignoring unmarshal or decode options).
|
||||
// It does not terminate the output with a newline.
|
||||
//
|
||||
// Type-specific marshal functions and methods take precedence
|
||||
// over the default representation of a value.
|
||||
// Functions or methods that operate on *T are only called when encoding
|
||||
// a value of type T (by taking its address) or a non-nil value of *T.
|
||||
// Marshal ensures that a value is always addressable
|
||||
// (by boxing it on the heap if necessary) so that
|
||||
// these functions and methods can be consistently called. For performance,
|
||||
// it is recommended that Marshal be passed a non-nil pointer to the value.
|
||||
//
|
||||
// The input value is encoded as JSON according the following rules:
|
||||
//
|
||||
// - If any type-specific functions in a [WithMarshalers] option match
|
||||
// the value type, then those functions are called to encode the value.
|
||||
// If all applicable functions return [SkipFunc],
|
||||
// then the value is encoded according to subsequent rules.
|
||||
//
|
||||
// - If the value type implements [MarshalerTo],
|
||||
// then the MarshalJSONTo method is called to encode the value.
|
||||
//
|
||||
// - If the value type implements [Marshaler],
|
||||
// then the MarshalJSON method is called to encode the value.
|
||||
//
|
||||
// - If the value type implements [encoding.TextAppender],
|
||||
// then the AppendText method is called to encode the value and
|
||||
// subsequently encode its result as a JSON string.
|
||||
//
|
||||
// - If the value type implements [encoding.TextMarshaler],
|
||||
// then the MarshalText method is called to encode the value and
|
||||
// subsequently encode its result as a JSON string.
|
||||
//
|
||||
// - Otherwise, the value is encoded according to the value's type
|
||||
// as described in detail below.
|
||||
//
|
||||
// Most Go types have a default JSON representation.
|
||||
// Certain types support specialized formatting according to
|
||||
// a format flag optionally specified in the Go struct tag
|
||||
// for the struct field that contains the current value
|
||||
// (see the “JSON Representation of Go structs” section for more details).
|
||||
//
|
||||
// The representation of each type is as follows:
|
||||
//
|
||||
// - A Go boolean is encoded as a JSON boolean (e.g., true or false).
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go string is encoded as a JSON string.
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go []byte or [N]byte is encoded as a JSON string containing
|
||||
// the binary value encoded using RFC 4648.
|
||||
// If the format is "base64" or unspecified, then this uses RFC 4648, section 4.
|
||||
// If the format is "base64url", then this uses RFC 4648, section 5.
|
||||
// If the format is "base32", then this uses RFC 4648, section 6.
|
||||
// If the format is "base32hex", then this uses RFC 4648, section 7.
|
||||
// If the format is "base16" or "hex", then this uses RFC 4648, section 8.
|
||||
// If the format is "array", then the bytes value is encoded as a JSON array
|
||||
// where each byte is recursively JSON-encoded as each JSON array element.
|
||||
//
|
||||
// - A Go integer is encoded as a JSON number without fractions or exponents.
|
||||
// If [StringifyNumbers] is specified or encoding a JSON object name,
|
||||
// then the JSON number is encoded within a JSON string.
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go float is encoded as a JSON number.
|
||||
// If [StringifyNumbers] is specified or encoding a JSON object name,
|
||||
// then the JSON number is encoded within a JSON string.
|
||||
// If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as
|
||||
// the JSON strings "NaN", "Infinity", and "-Infinity", respectively.
|
||||
// Otherwise, the presence of non-finite numbers results in a [SemanticError].
|
||||
//
|
||||
// - A Go map is encoded as a JSON object, where each Go map key and value
|
||||
// is recursively encoded as a name and value pair in the JSON object.
|
||||
// The Go map key must encode as a JSON string, otherwise this results
|
||||
// in a [SemanticError]. The Go map is traversed in a non-deterministic order.
|
||||
// For deterministic encoding, consider using the [Deterministic] option.
|
||||
// If the format is "emitnull", then a nil map is encoded as a JSON null.
|
||||
// If the format is "emitempty", then a nil map is encoded as an empty JSON object,
|
||||
// regardless of whether [FormatNilMapAsNull] is specified.
|
||||
// Otherwise by default, a nil map is encoded as an empty JSON object.
|
||||
//
|
||||
// - A Go struct is encoded as a JSON object.
|
||||
// See the “JSON Representation of Go structs” section
|
||||
// in the package-level documentation for more details.
|
||||
//
|
||||
// - A Go slice is encoded as a JSON array, where each Go slice element
|
||||
// is recursively JSON-encoded as the elements of the JSON array.
|
||||
// If the format is "emitnull", then a nil slice is encoded as a JSON null.
|
||||
// If the format is "emitempty", then a nil slice is encoded as an empty JSON array,
|
||||
// regardless of whether [FormatNilSliceAsNull] is specified.
|
||||
// Otherwise by default, a nil slice is encoded as an empty JSON array.
|
||||
//
|
||||
// - A Go array is encoded as a JSON array, where each Go array element
|
||||
// is recursively JSON-encoded as the elements of the JSON array.
|
||||
// The JSON array length is always identical to the Go array length.
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go pointer is encoded as a JSON null if nil, otherwise it is
|
||||
// the recursively JSON-encoded representation of the underlying value.
|
||||
// Format flags are forwarded to the encoding of the underlying value.
|
||||
//
|
||||
// - A Go interface is encoded as a JSON null if nil, otherwise it is
|
||||
// the recursively JSON-encoded representation of the underlying value.
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go [time.Time] is encoded as a JSON string containing the timestamp
|
||||
// formatted in RFC 3339 with nanosecond precision.
|
||||
// If the format matches one of the format constants declared
|
||||
// in the time package (e.g., RFC1123), then that format is used.
|
||||
// If the format is "unix", "unixmilli", "unixmicro", or "unixnano",
|
||||
// then the timestamp is encoded as a possibly fractional JSON number
|
||||
// of the number of seconds (or milliseconds, microseconds, or nanoseconds)
|
||||
// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.
|
||||
// To avoid a fractional component, round the timestamp to the relevant unit.
|
||||
// Otherwise, the format is used as-is with [time.Time.Format] if non-empty.
|
||||
//
|
||||
// - A Go [time.Duration] currently has no default representation and
|
||||
// requires an explicit format to be specified.
|
||||
// If the format is "sec", "milli", "micro", or "nano",
|
||||
// then the duration is encoded as a possibly fractional JSON number
|
||||
// of the number of seconds (or milliseconds, microseconds, or nanoseconds).
|
||||
// To avoid a fractional component, round the duration to the relevant unit.
|
||||
// If the format is "units", it is encoded as a JSON string formatted using
|
||||
// [time.Duration.String] (e.g., "1h30m" for 1 hour 30 minutes).
|
||||
// If the format is "iso8601", it is encoded as a JSON string using the
|
||||
// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)
|
||||
// using only accurate units of hours, minutes, and seconds.
|
||||
//
|
||||
// - All other Go types (e.g., complex numbers, channels, and functions)
|
||||
// have no default representation and result in a [SemanticError].
|
||||
//
|
||||
// JSON cannot represent cyclic data structures and Marshal does not handle them.
|
||||
// Passing cyclic structures will result in an error.
|
||||
func Marshal(in any, opts ...Options) (out []byte, err error) {
|
||||
return json.Marshal(in, opts...)
|
||||
}
|
||||
|
||||
// MarshalWrite serializes a Go value into an [io.Writer] according to the provided
|
||||
// marshal and encode options (while ignoring unmarshal or decode options).
|
||||
// It does not terminate the output with a newline.
|
||||
// See [Marshal] for details about the conversion of a Go value into JSON.
|
||||
func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) {
|
||||
return json.MarshalWrite(out, in, opts...)
|
||||
}
|
||||
|
||||
// MarshalEncode serializes a Go value into an [jsontext.Encoder] according to
|
||||
// the provided marshal options (while ignoring unmarshal, encode, or decode options).
|
||||
// Any marshal-relevant options already specified on the [jsontext.Encoder]
|
||||
// take lower precedence than the set of options provided by the caller.
|
||||
// Unlike [Marshal] and [MarshalWrite], encode options are ignored because
|
||||
// they must have already been specified on the provided [jsontext.Encoder].
|
||||
//
|
||||
// See [Marshal] for details about the conversion of a Go value into JSON.
|
||||
func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) {
|
||||
return json.MarshalEncode(out, in, opts...)
|
||||
}
|
||||
|
||||
// Unmarshal decodes a []byte input into a Go value according to the provided
|
||||
// unmarshal and decode options (while ignoring marshal or encode options).
|
||||
// The input must be a single JSON value with optional whitespace interspersed.
|
||||
// The output must be a non-nil pointer.
|
||||
//
|
||||
// Type-specific unmarshal functions and methods take precedence
|
||||
// over the default representation of a value.
|
||||
// Functions or methods that operate on *T are only called when decoding
|
||||
// a value of type T (by taking its address) or a non-nil value of *T.
|
||||
// Unmarshal ensures that a value is always addressable
|
||||
// (by boxing it on the heap if necessary) so that
|
||||
// these functions and methods can be consistently called.
|
||||
//
|
||||
// The input is decoded into the output according the following rules:
|
||||
//
|
||||
// - If any type-specific functions in a [WithUnmarshalers] option match
|
||||
// the value type, then those functions are called to decode the JSON
|
||||
// value. If all applicable functions return [SkipFunc],
|
||||
// then the input is decoded according to subsequent rules.
|
||||
//
|
||||
// - If the value type implements [UnmarshalerFrom],
|
||||
// then the UnmarshalJSONFrom method is called to decode the JSON value.
|
||||
//
|
||||
// - If the value type implements [Unmarshaler],
|
||||
// then the UnmarshalJSON method is called to decode the JSON value.
|
||||
//
|
||||
// - If the value type implements [encoding.TextUnmarshaler],
|
||||
// then the input is decoded as a JSON string and
|
||||
// the UnmarshalText method is called with the decoded string value.
|
||||
// This fails with a [SemanticError] if the input is not a JSON string.
|
||||
//
|
||||
// - Otherwise, the JSON value is decoded according to the value's type
|
||||
// as described in detail below.
|
||||
//
|
||||
// Most Go types have a default JSON representation.
|
||||
// Certain types support specialized formatting according to
|
||||
// a format flag optionally specified in the Go struct tag
|
||||
// for the struct field that contains the current value
|
||||
// (see the “JSON Representation of Go structs” section for more details).
|
||||
// A JSON null may be decoded into every supported Go value where
|
||||
// it is equivalent to storing the zero value of the Go value.
|
||||
// If the input JSON kind is not handled by the current Go value type,
|
||||
// then this fails with a [SemanticError]. Unless otherwise specified,
|
||||
// the decoded value replaces any pre-existing value.
|
||||
//
|
||||
// The representation of each type is as follows:
|
||||
//
|
||||
// - A Go boolean is decoded from a JSON boolean (e.g., true or false).
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go string is decoded from a JSON string.
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go []byte or [N]byte is decoded from a JSON string
|
||||
// containing the binary value encoded using RFC 4648.
|
||||
// If the format is "base64" or unspecified, then this uses RFC 4648, section 4.
|
||||
// If the format is "base64url", then this uses RFC 4648, section 5.
|
||||
// If the format is "base32", then this uses RFC 4648, section 6.
|
||||
// If the format is "base32hex", then this uses RFC 4648, section 7.
|
||||
// If the format is "base16" or "hex", then this uses RFC 4648, section 8.
|
||||
// If the format is "array", then the Go slice or array is decoded from a
|
||||
// JSON array where each JSON element is recursively decoded for each byte.
|
||||
// When decoding into a non-nil []byte, the slice length is reset to zero
|
||||
// and the decoded input is appended to it.
|
||||
// When decoding into a [N]byte, the input must decode to exactly N bytes,
|
||||
// otherwise it fails with a [SemanticError].
|
||||
//
|
||||
// - A Go integer is decoded from a JSON number.
|
||||
// It must be decoded from a JSON string containing a JSON number
|
||||
// if [StringifyNumbers] is specified or decoding a JSON object name.
|
||||
// It fails with a [SemanticError] if the JSON number
|
||||
// has a fractional or exponent component.
|
||||
// It also fails if it overflows the representation of the Go integer type.
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go float is decoded from a JSON number.
|
||||
// It must be decoded from a JSON string containing a JSON number
|
||||
// if [StringifyNumbers] is specified or decoding a JSON object name.
|
||||
// It fails if it overflows the representation of the Go float type.
|
||||
// If the format is "nonfinite", then the JSON strings
|
||||
// "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf.
|
||||
// Otherwise, the presence of such strings results in a [SemanticError].
|
||||
//
|
||||
// - A Go map is decoded from a JSON object,
|
||||
// where each JSON object name and value pair is recursively decoded
|
||||
// as the Go map key and value. Maps are not cleared.
|
||||
// If the Go map is nil, then a new map is allocated to decode into.
|
||||
// If the decoded key matches an existing Go map entry, the entry value
|
||||
// is reused by decoding the JSON object value into it.
|
||||
// The formats "emitnull" and "emitempty" have no effect when decoding.
|
||||
//
|
||||
// - A Go struct is decoded from a JSON object.
|
||||
// See the “JSON Representation of Go structs” section
|
||||
// in the package-level documentation for more details.
|
||||
//
|
||||
// - A Go slice is decoded from a JSON array, where each JSON element
|
||||
// is recursively decoded and appended to the Go slice.
|
||||
// Before appending into a Go slice, a new slice is allocated if it is nil,
|
||||
// otherwise the slice length is reset to zero.
|
||||
// The formats "emitnull" and "emitempty" have no effect when decoding.
|
||||
//
|
||||
// - A Go array is decoded from a JSON array, where each JSON array element
|
||||
// is recursively decoded as each corresponding Go array element.
|
||||
// Each Go array element is zeroed before decoding into it.
|
||||
// It fails with a [SemanticError] if the JSON array does not contain
|
||||
// the exact same number of elements as the Go array.
|
||||
// It does not support any custom format flags.
|
||||
//
|
||||
// - A Go pointer is decoded based on the JSON kind and underlying Go type.
|
||||
// If the input is a JSON null, then this stores a nil pointer.
|
||||
// Otherwise, it allocates a new underlying value if the pointer is nil,
|
||||
// and recursively JSON decodes into the underlying value.
|
||||
// Format flags are forwarded to the decoding of the underlying type.
|
||||
//
|
||||
// - A Go interface is decoded based on the JSON kind and underlying Go type.
|
||||
// If the input is a JSON null, then this stores a nil interface value.
|
||||
// Otherwise, a nil interface value of an empty interface type is initialized
|
||||
// with a zero Go bool, string, float64, map[string]any, or []any if the
|
||||
// input is a JSON boolean, string, number, object, or array, respectively.
|
||||
// If the interface value is still nil, then this fails with a [SemanticError]
|
||||
// since decoding could not determine an appropriate Go type to decode into.
|
||||
// For example, unmarshaling into a nil io.Reader fails since
|
||||
// there is no concrete type to populate the interface value with.
|
||||
// Otherwise an underlying value exists and it recursively decodes
|
||||
// the JSON input into it. It does not support any custom format flags.
|
||||
//
|
||||
// - A Go [time.Time] is decoded from a JSON string containing the time
|
||||
// formatted in RFC 3339 with nanosecond precision.
|
||||
// If the format matches one of the format constants declared in
|
||||
// the time package (e.g., RFC1123), then that format is used for parsing.
|
||||
// If the format is "unix", "unixmilli", "unixmicro", or "unixnano",
|
||||
// then the timestamp is decoded from an optionally fractional JSON number
|
||||
// of the number of seconds (or milliseconds, microseconds, or nanoseconds)
|
||||
// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.
|
||||
// Otherwise, the format is used as-is with [time.Time.Parse] if non-empty.
|
||||
//
|
||||
// - A Go [time.Duration] currently has no default representation and
|
||||
// requires an explicit format to be specified.
|
||||
// If the format is "sec", "milli", "micro", or "nano",
|
||||
// then the duration is decoded from an optionally fractional JSON number
|
||||
// of the number of seconds (or milliseconds, microseconds, or nanoseconds).
|
||||
// If the format is "units", it is decoded from a JSON string parsed using
|
||||
// [time.ParseDuration] (e.g., "1h30m" for 1 hour 30 minutes).
|
||||
// If the format is "iso8601", it is decoded from a JSON string using the
|
||||
// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)
|
||||
// accepting only accurate units of hours, minutes, or seconds.
|
||||
//
|
||||
// - All other Go types (e.g., complex numbers, channels, and functions)
|
||||
// have no default representation and result in a [SemanticError].
|
||||
//
|
||||
// In general, unmarshaling follows merge semantics (similar to RFC 7396)
|
||||
// where the decoded Go value replaces the destination value
|
||||
// for any JSON kind other than an object.
|
||||
// For JSON objects, the input object is merged into the destination value
|
||||
// where matching object members recursively apply merge semantics.
|
||||
func Unmarshal(in []byte, out any, opts ...Options) (err error) {
|
||||
return json.Unmarshal(in, out, opts...)
|
||||
}
|
||||
|
||||
// UnmarshalRead deserializes a Go value from an [io.Reader] according to the
|
||||
// provided unmarshal and decode options (while ignoring marshal or encode options).
|
||||
// The input must be a single JSON value with optional whitespace interspersed.
|
||||
// It consumes the entirety of [io.Reader] until [io.EOF] is encountered,
|
||||
// without reporting an error for EOF. The output must be a non-nil pointer.
|
||||
// See [Unmarshal] for details about the conversion of JSON into a Go value.
|
||||
func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) {
|
||||
return json.UnmarshalRead(in, out, opts...)
|
||||
}
|
||||
|
||||
// UnmarshalDecode deserializes a Go value from a [jsontext.Decoder] according to
|
||||
// the provided unmarshal options (while ignoring marshal, encode, or decode options).
|
||||
// Any unmarshal options already specified on the [jsontext.Decoder]
|
||||
// take lower precedence than the set of options provided by the caller.
|
||||
// Unlike [Unmarshal] and [UnmarshalRead], decode options are ignored because
|
||||
// they must have already been specified on the provided [jsontext.Decoder].
|
||||
//
|
||||
// The input may be a stream of one or more JSON values,
|
||||
// where this only unmarshals the next JSON value in the stream.
|
||||
// The output must be a non-nil pointer.
|
||||
// See [Unmarshal] for details about the conversion of JSON into a Go value.
|
||||
func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error) {
|
||||
return json.UnmarshalDecode(in, out, opts...)
|
||||
}
|
||||
|
||||
// SkipFunc may be returned by [MarshalToFunc] and [UnmarshalFromFunc] functions.
|
||||
//
|
||||
// Any function that returns SkipFunc must not cause observable side effects
|
||||
// on the provided [jsontext.Encoder] or [jsontext.Decoder].
|
||||
// For example, it is permissible to call [jsontext.Decoder.PeekKind],
|
||||
// but not permissible to call [jsontext.Decoder.ReadToken] or
|
||||
// [jsontext.Encoder.WriteToken] since such methods mutate the state.
|
||||
var SkipFunc = json.SkipFunc
|
||||
|
||||
// Marshalers is a list of functions that may override the marshal behavior
|
||||
// of specific types. Populate [WithMarshalers] to use it with
|
||||
// [Marshal], [MarshalWrite], or [MarshalEncode].
|
||||
// A nil *Marshalers is equivalent to an empty list.
|
||||
// There are no exported fields or methods on Marshalers.
|
||||
type Marshalers = json.Marshalers
|
||||
|
||||
// JoinMarshalers constructs a flattened list of marshal functions.
|
||||
// If multiple functions in the list are applicable for a value of a given type,
|
||||
// then those earlier in the list take precedence over those that come later.
|
||||
// If a function returns [SkipFunc], then the next applicable function is called,
|
||||
// otherwise the default marshaling behavior is used.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// m1 := JoinMarshalers(f1, f2)
|
||||
// m2 := JoinMarshalers(f0, m1, f3) // equivalent to m3
|
||||
// m3 := JoinMarshalers(f0, f1, f2, f3) // equivalent to m2
|
||||
func JoinMarshalers(ms ...*Marshalers) *Marshalers {
|
||||
return json.JoinMarshalers(ms...)
|
||||
}
|
||||
|
||||
// Unmarshalers is a list of functions that may override the unmarshal behavior
|
||||
// of specific types. Populate [WithUnmarshalers] to use it with
|
||||
// [Unmarshal], [UnmarshalRead], or [UnmarshalDecode].
|
||||
// A nil *Unmarshalers is equivalent to an empty list.
|
||||
// There are no exported fields or methods on Unmarshalers.
|
||||
type Unmarshalers = json.Unmarshalers
|
||||
|
||||
// JoinUnmarshalers constructs a flattened list of unmarshal functions.
|
||||
// If multiple functions in the list are applicable for a value of a given type,
|
||||
// then those earlier in the list take precedence over those that come later.
|
||||
// If a function returns [SkipFunc], then the next applicable function is called,
|
||||
// otherwise the default unmarshaling behavior is used.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// u1 := JoinUnmarshalers(f1, f2)
|
||||
// u2 := JoinUnmarshalers(f0, u1, f3) // equivalent to u3
|
||||
// u3 := JoinUnmarshalers(f0, f1, f2, f3) // equivalent to u2
|
||||
func JoinUnmarshalers(us ...*Unmarshalers) *Unmarshalers {
|
||||
return json.JoinUnmarshalers(us...)
|
||||
}
|
||||
|
||||
// MarshalFunc constructs a type-specific marshaler that
|
||||
// specifies how to marshal values of type T.
|
||||
// T can be any type except a named pointer.
|
||||
// The function is always provided with a non-nil pointer value
|
||||
// if T is an interface or pointer type.
|
||||
//
|
||||
// The function must marshal exactly one JSON value.
|
||||
// The value of T must not be retained outside the function call.
|
||||
// It may not return [SkipFunc].
|
||||
func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers {
|
||||
return json.MarshalFunc[T](fn)
|
||||
}
|
||||
|
||||
// MarshalToFunc constructs a type-specific marshaler that
|
||||
// specifies how to marshal values of type T.
|
||||
// T can be any type except a named pointer.
|
||||
// The function is always provided with a non-nil pointer value
|
||||
// if T is an interface or pointer type.
|
||||
//
|
||||
// The function must marshal exactly one JSON value by calling write methods
|
||||
// on the provided encoder. It may return [SkipFunc] such that marshaling can
|
||||
// move on to the next marshal function. However, no mutable method calls may
|
||||
// be called on the encoder if [SkipFunc] is returned.
|
||||
// The pointer to [jsontext.Encoder] and the value of T
|
||||
// must not be retained outside the function call.
|
||||
func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers {
|
||||
return json.MarshalToFunc[T](fn)
|
||||
}
|
||||
|
||||
// UnmarshalFunc constructs a type-specific unmarshaler that
|
||||
// specifies how to unmarshal values of type T.
|
||||
// T must be an unnamed pointer or an interface type.
|
||||
// The function is always provided with a non-nil pointer value.
|
||||
//
|
||||
// The function must unmarshal exactly one JSON value.
|
||||
// The input []byte must not be mutated.
|
||||
// The input []byte and value T must not be retained outside the function call.
|
||||
// It may not return [SkipFunc].
|
||||
func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers {
|
||||
return json.UnmarshalFunc[T](fn)
|
||||
}
|
||||
|
||||
// UnmarshalFromFunc constructs a type-specific unmarshaler that
|
||||
// specifies how to unmarshal values of type T.
|
||||
// T must be an unnamed pointer or an interface type.
|
||||
// The function is always provided with a non-nil pointer value.
|
||||
//
|
||||
// The function must unmarshal exactly one JSON value by calling read methods
|
||||
// on the provided decoder. It may return [SkipFunc] such that unmarshaling can
|
||||
// move on to the next unmarshal function. However, no mutable method calls may
|
||||
// be called on the decoder if [SkipFunc] is returned.
|
||||
// The pointer to [jsontext.Decoder] and the value of T
|
||||
// must not be retained outside the function call.
|
||||
func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers {
|
||||
return json.UnmarshalFromFunc[T](fn)
|
||||
}
|
||||
|
||||
// Marshaler is implemented by types that can marshal themselves.
|
||||
// It is recommended that types implement [MarshalerTo] unless the implementation
|
||||
// is trying to avoid a hard dependency on the "jsontext" package.
|
||||
//
|
||||
// It is recommended that implementations return a buffer that is safe
|
||||
// for the caller to retain and potentially mutate.
|
||||
type Marshaler = json.Marshaler
|
||||
|
||||
// MarshalerTo is implemented by types that can marshal themselves.
|
||||
// It is recommended that types implement MarshalerTo instead of [Marshaler]
|
||||
// since this is both more performant and flexible.
|
||||
// If a type implements both Marshaler and MarshalerTo,
|
||||
// then MarshalerTo takes precedence. In such a case, both implementations
|
||||
// should aim to have equivalent behavior for the default marshal options.
|
||||
//
|
||||
// The implementation must write only one JSON value to the Encoder and
|
||||
// must not retain the pointer to [jsontext.Encoder].
|
||||
type MarshalerTo = json.MarshalerTo
|
||||
|
||||
// Unmarshaler is implemented by types that can unmarshal themselves.
|
||||
// It is recommended that types implement [UnmarshalerFrom] unless the implementation
|
||||
// is trying to avoid a hard dependency on the "jsontext" package.
|
||||
//
|
||||
// The input can be assumed to be a valid encoding of a JSON value
|
||||
// if called from unmarshal functionality in this package.
|
||||
// UnmarshalJSON must copy the JSON data if it is retained after returning.
|
||||
// It is recommended that UnmarshalJSON implement merge semantics when
|
||||
// unmarshaling into a pre-populated value.
|
||||
//
|
||||
// Implementations must not retain or mutate the input []byte.
|
||||
type Unmarshaler = json.Unmarshaler
|
||||
|
||||
// UnmarshalerFrom is implemented by types that can unmarshal themselves.
|
||||
// It is recommended that types implement UnmarshalerFrom instead of [Unmarshaler]
|
||||
// since this is both more performant and flexible.
|
||||
// If a type implements both Unmarshaler and UnmarshalerFrom,
|
||||
// then UnmarshalerFrom takes precedence. In such a case, both implementations
|
||||
// should aim to have equivalent behavior for the default unmarshal options.
|
||||
//
|
||||
// The implementation must read only one JSON value from the Decoder.
|
||||
// It is recommended that UnmarshalJSONFrom implement merge semantics when
|
||||
// unmarshaling into a pre-populated value.
|
||||
//
|
||||
// Implementations must not retain the pointer to [jsontext.Decoder].
|
||||
type UnmarshalerFrom = json.UnmarshalerFrom
|
||||
|
||||
// ErrUnknownName indicates that a JSON object member could not be
|
||||
// unmarshaled because the name is not known to the target Go struct.
|
||||
// This error is directly wrapped within a [SemanticError] when produced.
|
||||
//
|
||||
// The name of an unknown JSON object member can be extracted as:
|
||||
//
|
||||
// err := ...
|
||||
// var serr json.SemanticError
|
||||
// if errors.As(err, &serr) && serr.Err == json.ErrUnknownName {
|
||||
// ptr := serr.JSONPointer // JSON pointer to unknown name
|
||||
// name := ptr.LastToken() // unknown name itself
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// This error is only returned if [RejectUnknownMembers] is true.
|
||||
var ErrUnknownName = json.ErrUnknownName
|
||||
|
||||
// SemanticError describes an error determining the meaning
|
||||
// of JSON data as Go data or vice-versa.
|
||||
//
|
||||
// The contents of this error as produced by this package may change over time.
|
||||
type SemanticError = json.SemanticError
|
||||
|
||||
// Options configure [Marshal], [MarshalWrite], [MarshalEncode],
|
||||
// [Unmarshal], [UnmarshalRead], and [UnmarshalDecode] with specific features.
|
||||
// Each function takes in a variadic list of options, where properties
|
||||
// set in later options override the value of previously set properties.
|
||||
//
|
||||
// The Options type is identical to [encoding/json.Options] and
|
||||
// [encoding/json/jsontext.Options]. Options from the other packages can
|
||||
// be used interchangeably with functionality in this package.
|
||||
//
|
||||
// Options represent either a singular option or a set of options.
|
||||
// It can be functionally thought of as a Go map of option properties
|
||||
// (even though the underlying implementation avoids Go maps for performance).
|
||||
//
|
||||
// The constructors (e.g., [Deterministic]) return a singular option value:
|
||||
//
|
||||
// opt := Deterministic(true)
|
||||
//
|
||||
// which is analogous to creating a single entry map:
|
||||
//
|
||||
// opt := Options{"Deterministic": true}
|
||||
//
|
||||
// [JoinOptions] composes multiple options values to together:
|
||||
//
|
||||
// out := JoinOptions(opts...)
|
||||
//
|
||||
// which is analogous to making a new map and copying the options over:
|
||||
//
|
||||
// out := make(Options)
|
||||
// for _, m := range opts {
|
||||
// for k, v := range m {
|
||||
// out[k] = v
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// [GetOption] looks up the value of options parameter:
|
||||
//
|
||||
// v, ok := GetOption(opts, Deterministic)
|
||||
//
|
||||
// which is analogous to a Go map lookup:
|
||||
//
|
||||
// v, ok := Options["Deterministic"]
|
||||
//
|
||||
// There is a single Options type, which is used with both marshal and unmarshal.
|
||||
// Some options affect both operations, while others only affect one operation:
|
||||
//
|
||||
// - [StringifyNumbers] affects marshaling and unmarshaling
|
||||
// - [Deterministic] affects marshaling only
|
||||
// - [FormatNilSliceAsNull] affects marshaling only
|
||||
// - [FormatNilMapAsNull] affects marshaling only
|
||||
// - [OmitZeroStructFields] affects marshaling only
|
||||
// - [MatchCaseInsensitiveNames] affects marshaling and unmarshaling
|
||||
// - [DiscardUnknownMembers] affects marshaling only
|
||||
// - [RejectUnknownMembers] affects unmarshaling only
|
||||
// - [WithMarshalers] affects marshaling only
|
||||
// - [WithUnmarshalers] affects unmarshaling only
|
||||
//
|
||||
// Options that do not affect a particular operation are ignored.
|
||||
type Options = json.Options
|
||||
|
||||
// JoinOptions coalesces the provided list of options into a single Options.
|
||||
// Properties set in later options override the value of previously set properties.
|
||||
func JoinOptions(srcs ...Options) Options {
|
||||
return json.JoinOptions(srcs...)
|
||||
}
|
||||
|
||||
// GetOption returns the value stored in opts with the provided setter,
|
||||
// reporting whether the value is present.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// v, ok := json.GetOption(opts, json.Deterministic)
|
||||
//
|
||||
// Options are most commonly introspected to alter the JSON representation of
|
||||
// [MarshalerTo.MarshalJSONTo] and [UnmarshalerFrom.UnmarshalJSONFrom] methods, and
|
||||
// [MarshalToFunc] and [UnmarshalFromFunc] functions.
|
||||
// In such cases, the presence bit should generally be ignored.
|
||||
func GetOption[T any](opts Options, setter func(T) Options) (T, bool) {
|
||||
return json.GetOption[T](opts, setter)
|
||||
}
|
||||
|
||||
// DefaultOptionsV2 is the full set of all options that define v2 semantics.
|
||||
// It is equivalent to all options under [Options], [encoding/json.Options],
|
||||
// and [encoding/json/jsontext.Options] being set to false or the zero value,
|
||||
// except for the options related to whitespace formatting.
|
||||
func DefaultOptionsV2() Options {
|
||||
return json.DefaultOptionsV2()
|
||||
}
|
||||
|
||||
// StringifyNumbers specifies that numeric Go types should be marshaled
|
||||
// as a JSON string containing the equivalent JSON number value.
|
||||
// When unmarshaling, numeric Go types are parsed from a JSON string
|
||||
// containing the JSON number without any surrounding whitespace.
|
||||
//
|
||||
// According to RFC 8259, section 6, a JSON implementation may choose to
|
||||
// limit the representation of a JSON number to an IEEE 754 binary64 value.
|
||||
// This may cause decoders to lose precision for int64 and uint64 types.
|
||||
// Quoting JSON numbers as a JSON string preserves the exact precision.
|
||||
//
|
||||
// This affects either marshaling or unmarshaling.
|
||||
func StringifyNumbers(v bool) Options {
|
||||
return json.StringifyNumbers(v)
|
||||
}
|
||||
|
||||
// Deterministic specifies that the same input value will be serialized
|
||||
// as the exact same output bytes. Different processes of
|
||||
// the same program will serialize equal values to the same bytes,
|
||||
// but different versions of the same program are not guaranteed
|
||||
// to produce the exact same sequence of bytes.
|
||||
//
|
||||
// This only affects marshaling and is ignored when unmarshaling.
|
||||
func Deterministic(v bool) Options {
|
||||
return json.Deterministic(v)
|
||||
}
|
||||
|
||||
// FormatNilSliceAsNull specifies that a nil Go slice should marshal as a
|
||||
// JSON null instead of the default representation as an empty JSON array
|
||||
// (or an empty JSON string in the case of ~[]byte).
|
||||
// Slice fields explicitly marked with `format:emitempty` still marshal
|
||||
// as an empty JSON array.
|
||||
//
|
||||
// This only affects marshaling and is ignored when unmarshaling.
|
||||
func FormatNilSliceAsNull(v bool) Options {
|
||||
return json.FormatNilSliceAsNull(v)
|
||||
}
|
||||
|
||||
// FormatNilMapAsNull specifies that a nil Go map should marshal as a
|
||||
// JSON null instead of the default representation as an empty JSON object.
|
||||
// Map fields explicitly marked with `format:emitempty` still marshal
|
||||
// as an empty JSON object.
|
||||
//
|
||||
// This only affects marshaling and is ignored when unmarshaling.
|
||||
func FormatNilMapAsNull(v bool) Options {
|
||||
return json.FormatNilMapAsNull(v)
|
||||
}
|
||||
|
||||
// OmitZeroStructFields specifies that a Go struct should marshal in such a way
|
||||
// that all struct fields that are zero are omitted from the marshaled output
|
||||
// if the value is zero as determined by the "IsZero() bool" method if present,
|
||||
// otherwise based on whether the field is the zero Go value.
|
||||
// This is semantically equivalent to specifying the `omitzero` tag option
|
||||
// on every field in a Go struct.
|
||||
//
|
||||
// This only affects marshaling and is ignored when unmarshaling.
|
||||
func OmitZeroStructFields(v bool) Options {
|
||||
return json.OmitZeroStructFields(v)
|
||||
}
|
||||
|
||||
// MatchCaseInsensitiveNames specifies that JSON object members are matched
|
||||
// against Go struct fields using a case-insensitive match of the name.
|
||||
// Go struct fields explicitly marked with `case:strict` or `case:ignore`
|
||||
// always use case-sensitive (or case-insensitive) name matching,
|
||||
// regardless of the value of this option.
|
||||
//
|
||||
// This affects either marshaling or unmarshaling.
|
||||
// For marshaling, this option may alter the detection of duplicate names
|
||||
// (assuming [jsontext.AllowDuplicateNames] is false) from inlined fields
|
||||
// if it matches one of the declared fields in the Go struct.
|
||||
func MatchCaseInsensitiveNames(v bool) Options {
|
||||
return json.MatchCaseInsensitiveNames(v)
|
||||
}
|
||||
|
||||
// DiscardUnknownMembers specifies that marshaling should ignore any
|
||||
// JSON object members stored in Go struct fields dedicated to storing
|
||||
// unknown JSON object members.
|
||||
//
|
||||
// This only affects marshaling and is ignored when unmarshaling.
|
||||
func DiscardUnknownMembers(v bool) Options {
|
||||
return json.DiscardUnknownMembers(v)
|
||||
}
|
||||
|
||||
// RejectUnknownMembers specifies that unknown members should be rejected
|
||||
// when unmarshaling a JSON object, regardless of whether there is a field
|
||||
// to store unknown members.
|
||||
//
|
||||
// This only affects unmarshaling and is ignored when marshaling.
|
||||
func RejectUnknownMembers(v bool) Options {
|
||||
return json.RejectUnknownMembers(v)
|
||||
}
|
||||
|
||||
// WithMarshalers specifies a list of type-specific marshalers to use,
|
||||
// which can be used to override the default marshal behavior for values
|
||||
// of particular types.
|
||||
//
|
||||
// This only affects marshaling and is ignored when unmarshaling.
|
||||
func WithMarshalers(v *Marshalers) Options {
|
||||
return json.WithMarshalers(v)
|
||||
}
|
||||
|
||||
// WithUnmarshalers specifies a list of type-specific unmarshalers to use,
|
||||
// which can be used to override the default unmarshal behavior for values
|
||||
// of particular types.
|
||||
//
|
||||
// This only affects unmarshaling and is ignored when marshaling.
|
||||
func WithUnmarshalers(v *Unmarshalers) Options {
|
||||
return json.WithUnmarshalers(v)
|
||||
}
|
||||
76
vendor/github.com/go-json-experiment/json/arshal.go
generated
vendored
76
vendor/github.com/go-json-experiment/json/arshal.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
@@ -145,17 +147,23 @@ var export = jsontext.Internal.Export(&internal.AllowInternalUse)
|
||||
// If the format matches one of the format constants declared
|
||||
// in the time package (e.g., RFC1123), then that format is used.
|
||||
// If the format is "unix", "unixmilli", "unixmicro", or "unixnano",
|
||||
// then the timestamp is encoded as a JSON number of the number of seconds
|
||||
// (or milliseconds, microseconds, or nanoseconds) since the Unix epoch,
|
||||
// which is January 1st, 1970 at 00:00:00 UTC.
|
||||
// then the timestamp is encoded as a possibly fractional JSON number
|
||||
// of the number of seconds (or milliseconds, microseconds, or nanoseconds)
|
||||
// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.
|
||||
// To avoid a fractional component, round the timestamp to the relevant unit.
|
||||
// Otherwise, the format is used as-is with [time.Time.Format] if non-empty.
|
||||
//
|
||||
// - A Go [time.Duration] is encoded as a JSON string containing the duration
|
||||
// formatted according to [time.Duration.String].
|
||||
// - A Go [time.Duration] currently has no default representation and
|
||||
// requires an explicit format to be specified.
|
||||
// If the format is "sec", "milli", "micro", or "nano",
|
||||
// then the duration is encoded as a JSON number of the number of seconds
|
||||
// (or milliseconds, microseconds, or nanoseconds) in the duration.
|
||||
// If the format is "units", it uses [time.Duration.String].
|
||||
// then the duration is encoded as a possibly fractional JSON number
|
||||
// of the number of seconds (or milliseconds, microseconds, or nanoseconds).
|
||||
// To avoid a fractional component, round the duration to the relevant unit.
|
||||
// If the format is "units", it is encoded as a JSON string formatted using
|
||||
// [time.Duration.String] (e.g., "1h30m" for 1 hour 30 minutes).
|
||||
// If the format is "iso8601", it is encoded as a JSON string using the
|
||||
// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)
|
||||
// using only accurate units of hours, minutes, and seconds.
|
||||
//
|
||||
// - All other Go types (e.g., complex numbers, channels, and functions)
|
||||
// have no default representation and result in a [SemanticError].
|
||||
@@ -373,17 +381,21 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro
|
||||
// If the format matches one of the format constants declared in
|
||||
// the time package (e.g., RFC1123), then that format is used for parsing.
|
||||
// If the format is "unix", "unixmilli", "unixmicro", or "unixnano",
|
||||
// then the timestamp is decoded from a JSON number of the number of seconds
|
||||
// (or milliseconds, microseconds, or nanoseconds) since the Unix epoch,
|
||||
// which is January 1st, 1970 at 00:00:00 UTC.
|
||||
// then the timestamp is decoded from an optionally fractional JSON number
|
||||
// of the number of seconds (or milliseconds, microseconds, or nanoseconds)
|
||||
// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.
|
||||
// Otherwise, the format is used as-is with [time.Time.Parse] if non-empty.
|
||||
//
|
||||
// - A Go [time.Duration] is decoded from a JSON string by
|
||||
// passing the decoded string to [time.ParseDuration].
|
||||
// - A Go [time.Duration] currently has no default representation and
|
||||
// requires an explicit format to be specified.
|
||||
// If the format is "sec", "milli", "micro", or "nano",
|
||||
// then the duration is decoded from a JSON number of the number of seconds
|
||||
// (or milliseconds, microseconds, or nanoseconds) in the duration.
|
||||
// If the format is "units", it uses [time.ParseDuration].
|
||||
// then the duration is decoded from an optionally fractional JSON number
|
||||
// of the number of seconds (or milliseconds, microseconds, or nanoseconds).
|
||||
// If the format is "units", it is decoded from a JSON string parsed using
|
||||
// [time.ParseDuration] (e.g., "1h30m" for 1 hour 30 minutes).
|
||||
// If the format is "iso8601", it is decoded from a JSON string using the
|
||||
// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)
|
||||
// accepting only accurate units of hours, minutes, or seconds.
|
||||
//
|
||||
// - All other Go types (e.g., complex numbers, channels, and functions)
|
||||
// have no default representation and result in a [SemanticError].
|
||||
@@ -397,7 +409,7 @@ func Unmarshal(in []byte, out any, opts ...Options) (err error) {
|
||||
dec := export.GetBufferedDecoder(in, opts...)
|
||||
defer export.PutBufferedDecoder(dec)
|
||||
xd := export.Decoder(dec)
|
||||
err = unmarshalFull(dec, out, &xd.Struct)
|
||||
err = unmarshalDecode(dec, out, &xd.Struct, true)
|
||||
if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
|
||||
return internal.TransformUnmarshalError(out, err)
|
||||
}
|
||||
@@ -414,24 +426,13 @@ func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) {
|
||||
dec := export.GetStreamingDecoder(in, opts...)
|
||||
defer export.PutStreamingDecoder(dec)
|
||||
xd := export.Decoder(dec)
|
||||
err = unmarshalFull(dec, out, &xd.Struct)
|
||||
err = unmarshalDecode(dec, out, &xd.Struct, true)
|
||||
if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
|
||||
return internal.TransformUnmarshalError(out, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func unmarshalFull(in *jsontext.Decoder, out any, uo *jsonopts.Struct) error {
|
||||
switch err := unmarshalDecode(in, out, uo); err {
|
||||
case nil:
|
||||
return export.Decoder(in).CheckEOF()
|
||||
case io.EOF:
|
||||
return io.ErrUnexpectedEOF
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalDecode deserializes a Go value from a [jsontext.Decoder] according to
|
||||
// the provided unmarshal options (while ignoring marshal, encode, or decode options).
|
||||
// Any unmarshal options already specified on the [jsontext.Decoder]
|
||||
@@ -450,14 +451,14 @@ func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error)
|
||||
defer func() { xd.Struct = optsOriginal }()
|
||||
xd.Struct.JoinWithoutCoderOptions(opts...)
|
||||
}
|
||||
err = unmarshalDecode(in, out, &xd.Struct)
|
||||
err = unmarshalDecode(in, out, &xd.Struct, false)
|
||||
if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
|
||||
return internal.TransformUnmarshalError(out, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func unmarshalDecode(in *jsontext.Decoder, out any, uo *jsonopts.Struct) (err error) {
|
||||
func unmarshalDecode(in *jsontext.Decoder, out any, uo *jsonopts.Struct, last bool) (err error) {
|
||||
v := reflect.ValueOf(out)
|
||||
if v.Kind() != reflect.Pointer || v.IsNil() {
|
||||
return &SemanticError{action: "unmarshal", GoType: reflect.TypeOf(out), Err: internal.ErrNonNilReference}
|
||||
@@ -468,7 +469,11 @@ func unmarshalDecode(in *jsontext.Decoder, out any, uo *jsonopts.Struct) (err er
|
||||
// In legacy semantics, the entirety of the next JSON value
|
||||
// was validated before attempting to unmarshal it.
|
||||
if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
|
||||
if err := export.Decoder(in).CheckNextValue(); err != nil {
|
||||
if err := export.Decoder(in).CheckNextValue(last); err != nil {
|
||||
if err == io.EOF && last {
|
||||
offset := in.InputOffset() + int64(len(in.UnreadBuffer()))
|
||||
return &jsontext.SyntacticError{ByteOffset: offset, Err: io.ErrUnexpectedEOF}
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -482,8 +487,15 @@ func unmarshalDecode(in *jsontext.Decoder, out any, uo *jsonopts.Struct) (err er
|
||||
if !uo.Flags.Get(jsonflags.AllowDuplicateNames) {
|
||||
export.Decoder(in).Tokens.InvalidateDisabledNamespaces()
|
||||
}
|
||||
if err == io.EOF && last {
|
||||
offset := in.InputOffset() + int64(len(in.UnreadBuffer()))
|
||||
return &jsontext.SyntacticError{ByteOffset: offset, Err: io.ErrUnexpectedEOF}
|
||||
}
|
||||
return err
|
||||
}
|
||||
if last {
|
||||
return export.Decoder(in).CheckEOF()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/arshal_any.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/arshal_any.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
|
||||
24
vendor/github.com/go-json-experiment/json/arshal_default.go
generated
vendored
24
vendor/github.com/go-json-experiment/json/arshal_default.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
@@ -327,8 +329,9 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
|
||||
default:
|
||||
return newInvalidFormatError(enc, t, mo)
|
||||
}
|
||||
} else if mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) &&
|
||||
(va.Kind() == reflect.Array || hasMarshaler) {
|
||||
} else if mo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array {
|
||||
return marshalArray(enc, va, mo)
|
||||
} else if mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && hasMarshaler {
|
||||
return marshalArray(enc, va, mo)
|
||||
}
|
||||
if mo.Flags.Get(jsonflags.FormatNilSliceAsNull) && va.Kind() == reflect.Slice && va.IsNil() {
|
||||
@@ -364,8 +367,9 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
|
||||
default:
|
||||
return newInvalidFormatError(dec, t, uo)
|
||||
}
|
||||
} else if uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) &&
|
||||
(va.Kind() == reflect.Array || dec.PeekKind() == '[') {
|
||||
} else if uo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array {
|
||||
return unmarshalArray(dec, va, uo)
|
||||
} else if uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && dec.PeekKind() == '[' {
|
||||
return unmarshalArray(dec, va, uo)
|
||||
}
|
||||
var flags jsonwire.ValueFlags
|
||||
@@ -393,7 +397,7 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
|
||||
if err != nil {
|
||||
return newUnmarshalErrorAfter(dec, t, err)
|
||||
}
|
||||
if len(val) != encodedLen(len(b)) && !uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) {
|
||||
if len(val) != encodedLen(len(b)) && !uo.Flags.Get(jsonflags.ParseBytesWithLooseRFC4648) {
|
||||
// TODO(https://go.dev/issue/53845): RFC 4648, section 3.3,
|
||||
// specifies that non-alphabet characters must be rejected.
|
||||
// Unfortunately, the "base32" and "base64" packages allow
|
||||
@@ -1063,7 +1067,7 @@ func makeStructArshaler(t reflect.Type) *arshaler {
|
||||
}
|
||||
|
||||
// Check for the legacy definition of omitempty.
|
||||
if f.omitempty && mo.Flags.Get(jsonflags.OmitEmptyWithLegacyDefinition) && isLegacyEmpty(v) {
|
||||
if f.omitempty && mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) && isLegacyEmpty(v) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1078,7 +1082,7 @@ func makeStructArshaler(t reflect.Type) *arshaler {
|
||||
// OmitEmpty skips the field if the marshaled JSON value is empty,
|
||||
// which we can know up front if there are no custom marshalers,
|
||||
// otherwise we must marshal the value and unwrite it if empty.
|
||||
if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacyDefinition) &&
|
||||
if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) &&
|
||||
!nonDefault && f.isEmpty != nil && f.isEmpty(v) {
|
||||
continue // fast path for omitempty
|
||||
}
|
||||
@@ -1143,7 +1147,7 @@ func makeStructArshaler(t reflect.Type) *arshaler {
|
||||
}
|
||||
|
||||
// Try unwriting the member if empty (slow path for omitempty).
|
||||
if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacyDefinition) {
|
||||
if f.omitempty && !mo.Flags.Get(jsonflags.OmitEmptyWithLegacySemantics) {
|
||||
var prevName *string
|
||||
if prevIdx >= 0 {
|
||||
prevName = &fields.flattened[prevIdx].name
|
||||
@@ -1686,8 +1690,6 @@ func makePointerArshaler(t reflect.Type) *arshaler {
|
||||
return &fncs
|
||||
}
|
||||
|
||||
var errNilInterface = errors.New("cannot derive concrete type for nil interface with finite type set")
|
||||
|
||||
func makeInterfaceArshaler(t reflect.Type) *arshaler {
|
||||
// NOTE: Values retrieved from an interface are not addressable,
|
||||
// so we shallow copy the values to make them addressable and
|
||||
@@ -1793,7 +1795,7 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler {
|
||||
|
||||
k := dec.PeekKind()
|
||||
if !isAnyType(t) {
|
||||
return newUnmarshalErrorBeforeWithSkipping(dec, uo, t, errNilInterface)
|
||||
return newUnmarshalErrorBeforeWithSkipping(dec, uo, t, internal.ErrNilInterface)
|
||||
}
|
||||
switch k {
|
||||
case 'f', 't':
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/arshal_funcs.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/arshal_funcs.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
|
||||
4
vendor/github.com/go-json-experiment/json/arshal_inlined.go
generated
vendored
4
vendor/github.com/go-json-experiment/json/arshal_inlined.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
@@ -111,7 +113,7 @@ func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *j
|
||||
mk := newAddressableValue(m.Type().Key())
|
||||
mv := newAddressableValue(m.Type().Elem())
|
||||
marshalKey := func(mk addressableValue) error {
|
||||
b, err := jsonwire.AppendQuote(enc.UnusedBuffer(), mk.String(), &mo.Flags)
|
||||
b, err := jsonwire.AppendQuote(enc.AvailableBuffer(), mk.String(), &mo.Flags)
|
||||
if err != nil {
|
||||
return newMarshalErrorBefore(enc, m.Type().Key(), err)
|
||||
}
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/arshal_methods.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/arshal_methods.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
|
||||
199
vendor/github.com/go-json-experiment/json/arshal_time.go
generated
vendored
199
vendor/github.com/go-json-experiment/json/arshal_time.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
@@ -48,8 +50,11 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
|
||||
if !m.initFormat(mo.Format) {
|
||||
return newInvalidFormatError(enc, t, mo)
|
||||
}
|
||||
} else if mo.Flags.Get(jsonflags.FormatTimeWithLegacySemantics) {
|
||||
} else if mo.Flags.Get(jsonflags.FormatDurationAsNano) {
|
||||
return marshalNano(enc, va, mo)
|
||||
} else {
|
||||
// TODO(https://go.dev/issue/71631): Decide on default duration representation.
|
||||
return newMarshalErrorBefore(enc, t, errors.New("no default representation (see https://go.dev/issue/71631); specify an explicit format"))
|
||||
}
|
||||
|
||||
// TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo.
|
||||
@@ -71,8 +76,11 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
|
||||
if !u.initFormat(uo.Format) {
|
||||
return newInvalidFormatError(dec, t, uo)
|
||||
}
|
||||
} else if uo.Flags.Get(jsonflags.FormatTimeWithLegacySemantics) {
|
||||
} else if uo.Flags.Get(jsonflags.FormatDurationAsNano) {
|
||||
return unmarshalNano(dec, va, uo)
|
||||
} else {
|
||||
// TODO(https://go.dev/issue/71631): Decide on default duration representation.
|
||||
return newUnmarshalErrorBeforeWithSkipping(dec, uo, t, errors.New("no default representation (see https://go.dev/issue/71631); specify an explicit format"))
|
||||
}
|
||||
|
||||
stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers)
|
||||
@@ -142,7 +150,7 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
|
||||
if !u.initFormat(uo.Format) {
|
||||
return newInvalidFormatError(dec, t, uo)
|
||||
}
|
||||
} else if uo.Flags.Get(jsonflags.FormatTimeWithLegacySemantics) {
|
||||
} else if uo.Flags.Get(jsonflags.ParseTimeWithLooseRFC3339) {
|
||||
u.looseRFC3339 = true
|
||||
}
|
||||
|
||||
@@ -198,6 +206,7 @@ type durationArshaler struct {
|
||||
// - 0 uses time.Duration.String
|
||||
// - 1e0, 1e3, 1e6, or 1e9 use a decimal encoding of the duration as
|
||||
// nanoseconds, microseconds, milliseconds, or seconds.
|
||||
// - 8601 uses ISO 8601
|
||||
base uint64
|
||||
}
|
||||
|
||||
@@ -213,6 +222,8 @@ func (a *durationArshaler) initFormat(format string) (ok bool) {
|
||||
a.base = 1e3
|
||||
case "nano":
|
||||
a.base = 1e0
|
||||
case "iso8601":
|
||||
a.base = 8601
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -220,13 +231,15 @@ func (a *durationArshaler) initFormat(format string) (ok bool) {
|
||||
}
|
||||
|
||||
func (a *durationArshaler) isNumeric() bool {
|
||||
return a.base != 0 && a.base != 60
|
||||
return a.base != 0 && a.base != 8601
|
||||
}
|
||||
|
||||
func (a *durationArshaler) appendMarshal(b []byte) ([]byte, error) {
|
||||
switch a.base {
|
||||
case 0:
|
||||
return append(b, a.td.String()...), nil
|
||||
case 8601:
|
||||
return appendDurationISO8601(b, a.td), nil
|
||||
default:
|
||||
return appendDurationBase10(b, a.td, a.base), nil
|
||||
}
|
||||
@@ -236,6 +249,8 @@ func (a *durationArshaler) unmarshal(b []byte) (err error) {
|
||||
switch a.base {
|
||||
case 0:
|
||||
a.td, err = time.ParseDuration(string(b))
|
||||
case 8601:
|
||||
a.td, err = parseDurationISO8601(b)
|
||||
default:
|
||||
a.td, err = parseDurationBase10(b, a.base)
|
||||
}
|
||||
@@ -410,7 +425,7 @@ func appendDurationBase10(b []byte, d time.Duration, pow10 uint64) []byte {
|
||||
// parseDurationBase10 parses d from a decimal fractional number,
|
||||
// where pow10 is a power-of-10 used to scale up the number.
|
||||
func parseDurationBase10(b []byte, pow10 uint64) (time.Duration, error) {
|
||||
suffix, neg := consumeSign(b) // consume sign
|
||||
suffix, neg := consumeSign(b, false) // consume sign
|
||||
wholeBytes, fracBytes := bytesCutByte(suffix, '.', true) // consume whole and frac fields
|
||||
whole, okWhole := jsonwire.ParseUint(wholeBytes) // parse whole field; may overflow
|
||||
frac, okFrac := parseFracBase10(fracBytes, pow10) // parse frac field
|
||||
@@ -426,6 +441,166 @@ func parseDurationBase10(b []byte, pow10 uint64) (time.Duration, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// appendDurationISO8601 appends an ISO 8601 duration with a restricted grammar,
|
||||
// where leading and trailing zeroes and zero-value designators are omitted.
|
||||
// It only uses hour, minute, and second designators since ISO 8601 defines
|
||||
// those as being "accurate", while year, month, week, and day are "nominal".
|
||||
func appendDurationISO8601(b []byte, d time.Duration) []byte {
|
||||
if d == 0 {
|
||||
return append(b, "PT0S"...)
|
||||
}
|
||||
b, n := mayAppendDurationSign(b, d)
|
||||
b = append(b, "PT"...)
|
||||
n, nsec := bits.Div64(0, n, 1e9) // compute nsec field
|
||||
n, sec := bits.Div64(0, n, 60) // compute sec field
|
||||
hour, min := bits.Div64(0, n, 60) // compute hour and min fields
|
||||
if hour > 0 {
|
||||
b = append(strconv.AppendUint(b, hour, 10), 'H')
|
||||
}
|
||||
if min > 0 {
|
||||
b = append(strconv.AppendUint(b, min, 10), 'M')
|
||||
}
|
||||
if sec > 0 || nsec > 0 {
|
||||
b = append(appendFracBase10(strconv.AppendUint(b, sec, 10), nsec, 1e9), 'S')
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// daysPerYear is the exact average number of days in a year according to
|
||||
// the Gregorian calender, which has an extra day each year that is
|
||||
// a multiple of 4, unless it is evenly divisible by 100 but not by 400.
|
||||
// This does not take into account leap seconds, which are not deterministic.
|
||||
const daysPerYear = 365.2425
|
||||
|
||||
var errInaccurateDateUnits = errors.New("inaccurate year, month, week, or day units")
|
||||
|
||||
// parseDurationISO8601 parses a duration according to ISO 8601-1:2019,
|
||||
// section 5.5.2.2 and 5.5.2.3 with the following restrictions or extensions:
|
||||
//
|
||||
// - A leading minus sign is permitted for negative duration according
|
||||
// to ISO 8601-2:2019, section 4.4.1.9. We do not permit negative values
|
||||
// for each "time scale component", which is permitted by section 4.4.1.1,
|
||||
// but rarely supported by parsers.
|
||||
//
|
||||
// - A leading plus sign is permitted (and ignored).
|
||||
// This is not required by ISO 8601, but not forbidden either.
|
||||
// There is some precedent for this as it is supported by the principle of
|
||||
// duration arithmetic as specified in ISO 8601-2-2019, section 14.1.
|
||||
// Of note, the JavaScript grammar for ISO 8601 permits a leading plus sign.
|
||||
//
|
||||
// - A fractional value is only permitted for accurate units
|
||||
// (i.e., hour, minute, and seconds) in the last time component,
|
||||
// which is permissible by ISO 8601-1:2019, section 5.5.2.3.
|
||||
//
|
||||
// - Both periods ('.') and commas (',') are supported as the separator
|
||||
// between the integer part and fraction part of a number,
|
||||
// as specified in ISO 8601-1:2019, section 3.2.6.
|
||||
// While ISO 8601 recommends comma as the default separator,
|
||||
// most formatters uses a period.
|
||||
//
|
||||
// - Leading zeros are ignored. This is not required by ISO 8601,
|
||||
// but also not forbidden by the standard. Many parsers support this.
|
||||
//
|
||||
// - Lowercase designators are supported. This is not required by ISO 8601,
|
||||
// but also not forbidden by the standard. Many parsers support this.
|
||||
//
|
||||
// If the nominal units of year, month, week, or day are present,
|
||||
// this produces a best-effort value and also reports [errInaccurateDateUnits].
|
||||
//
|
||||
// The accepted grammar is identical to JavaScript's Duration:
|
||||
//
|
||||
// https://tc39.es/proposal-temporal/#prod-Duration
|
||||
//
|
||||
// We follow JavaScript's grammar as JSON itself is derived from JavaScript.
|
||||
// The Temporal.Duration.toJSON method is guaranteed to produce an output
|
||||
// that can be parsed by this function so long as arithmetic in JavaScript
|
||||
// do not use a largestUnit value higher than "hours" (which is the default).
|
||||
// Even if it does, this will do a best-effort parsing with inaccurate units,
|
||||
// but report [errInaccurateDateUnits].
|
||||
func parseDurationISO8601(b []byte) (time.Duration, error) {
|
||||
var invalid, overflow, inaccurate, sawFrac bool
|
||||
var sumNanos, n, co uint64
|
||||
|
||||
// cutBytes is like [bytes.Cut], but uses either c0 or c1 as the separator.
|
||||
cutBytes := func(b []byte, c0, c1 byte) (prefix, suffix []byte, ok bool) {
|
||||
for i, c := range b {
|
||||
if c == c0 || c == c1 {
|
||||
return b[:i], b[i+1:], true
|
||||
}
|
||||
}
|
||||
return b, nil, false
|
||||
}
|
||||
|
||||
// mayParseUnit attempts to parse another date or time number
|
||||
// identified by the desHi and desLo unit characters.
|
||||
// If the part is absent for current unit, it returns b as is.
|
||||
mayParseUnit := func(b []byte, desHi, desLo byte, unit time.Duration) []byte {
|
||||
number, suffix, ok := cutBytes(b, desHi, desLo)
|
||||
if !ok || sawFrac {
|
||||
return b // designator is not present or already saw fraction, which can only be in the last component
|
||||
}
|
||||
|
||||
// Parse the number.
|
||||
// A fraction allowed for the accurate units in the last part.
|
||||
whole, frac, ok := cutBytes(number, '.', ',')
|
||||
if ok {
|
||||
sawFrac = true
|
||||
invalid = invalid || len(frac) == len("") || unit > time.Hour
|
||||
if unit == time.Second {
|
||||
n, ok = parsePaddedBase10(frac, uint64(time.Second))
|
||||
invalid = invalid || !ok
|
||||
} else {
|
||||
f, err := strconv.ParseFloat("0."+string(frac), 64)
|
||||
invalid = invalid || err != nil || len(bytes.Trim(frac[len("."):], "0123456789")) > 0
|
||||
n = uint64(math.Round(f * float64(unit))) // never overflows since f is within [0..1]
|
||||
}
|
||||
sumNanos, co = bits.Add64(sumNanos, n, 0) // overflow if co > 0
|
||||
overflow = overflow || co > 0
|
||||
}
|
||||
for len(whole) > 1 && whole[0] == '0' {
|
||||
whole = whole[len("0"):] // trim leading zeros
|
||||
}
|
||||
n, ok := jsonwire.ParseUint(whole) // overflow if !ok && MaxUint64
|
||||
hi, lo := bits.Mul64(n, uint64(unit)) // overflow if hi > 0
|
||||
sumNanos, co = bits.Add64(sumNanos, lo, 0) // overflow if co > 0
|
||||
invalid = invalid || (!ok && n != math.MaxUint64)
|
||||
overflow = overflow || (!ok && n == math.MaxUint64) || hi > 0 || co > 0
|
||||
inaccurate = inaccurate || unit > time.Hour
|
||||
return suffix
|
||||
}
|
||||
|
||||
suffix, neg := consumeSign(b, true)
|
||||
prefix, suffix, okP := cutBytes(suffix, 'P', 'p')
|
||||
durDate, durTime, okT := cutBytes(suffix, 'T', 't')
|
||||
invalid = invalid || len(prefix) > 0 || !okP || (okT && len(durTime) == 0) || len(durDate)+len(durTime) == 0
|
||||
if len(durDate) > 0 { // nominal portion of the duration
|
||||
durDate = mayParseUnit(durDate, 'Y', 'y', time.Duration(daysPerYear*24*60*60*1e9))
|
||||
durDate = mayParseUnit(durDate, 'M', 'm', time.Duration(daysPerYear/12*24*60*60*1e9))
|
||||
durDate = mayParseUnit(durDate, 'W', 'w', time.Duration(7*24*60*60*1e9))
|
||||
durDate = mayParseUnit(durDate, 'D', 'd', time.Duration(24*60*60*1e9))
|
||||
invalid = invalid || len(durDate) > 0 // unknown elements
|
||||
}
|
||||
if len(durTime) > 0 { // accurate portion of the duration
|
||||
durTime = mayParseUnit(durTime, 'H', 'h', time.Duration(60*60*1e9))
|
||||
durTime = mayParseUnit(durTime, 'M', 'm', time.Duration(60*1e9))
|
||||
durTime = mayParseUnit(durTime, 'S', 's', time.Duration(1e9))
|
||||
invalid = invalid || len(durTime) > 0 // unknown elements
|
||||
}
|
||||
d := mayApplyDurationSign(sumNanos, neg)
|
||||
overflow = overflow || (neg != (d < 0) && d != 0) // overflows signed duration
|
||||
|
||||
switch {
|
||||
case invalid:
|
||||
return 0, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, strconv.ErrSyntax)
|
||||
case overflow:
|
||||
return 0, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, strconv.ErrRange)
|
||||
case inaccurate:
|
||||
return d, fmt.Errorf("invalid ISO 8601 duration %q: %w", b, errInaccurateDateUnits)
|
||||
default:
|
||||
return d, nil
|
||||
}
|
||||
}
|
||||
|
||||
// mayAppendDurationSign appends a negative sign if n is negative.
|
||||
func mayAppendDurationSign(b []byte, d time.Duration) ([]byte, uint64) {
|
||||
if d < 0 {
|
||||
@@ -469,7 +644,7 @@ func appendTimeUnix(b []byte, t time.Time, pow10 uint64) []byte {
|
||||
// parseTimeUnix parses t formatted as a decimal fractional number,
|
||||
// where pow10 is a power-of-10 used to scale down the number.
|
||||
func parseTimeUnix(b []byte, pow10 uint64) (time.Time, error) {
|
||||
suffix, neg := consumeSign(b) // consume sign
|
||||
suffix, neg := consumeSign(b, false) // consume sign
|
||||
wholeBytes, fracBytes := bytesCutByte(suffix, '.', true) // consume whole and frac fields
|
||||
whole, okWhole := jsonwire.ParseUint(wholeBytes) // parse whole field; may overflow
|
||||
frac, okFrac := parseFracBase10(fracBytes, 1e9/pow10) // parse frac field
|
||||
@@ -568,10 +743,14 @@ func parsePaddedBase10(b []byte, max10 uint64) (n uint64, ok bool) {
|
||||
return n, true
|
||||
}
|
||||
|
||||
// consumeSign consumes an optional leading negative sign.
|
||||
func consumeSign(b []byte) ([]byte, bool) {
|
||||
if len(b) > 0 && b[0] == '-' {
|
||||
return b[len("-"):], true
|
||||
// consumeSign consumes an optional leading negative or positive sign.
|
||||
func consumeSign(b []byte, allowPlus bool) ([]byte, bool) {
|
||||
if len(b) > 0 {
|
||||
if b[0] == '-' {
|
||||
return b[len("-"):], true
|
||||
} else if b[0] == '+' && allowPlus {
|
||||
return b[len("+"):], false
|
||||
}
|
||||
}
|
||||
return b, false
|
||||
}
|
||||
|
||||
96
vendor/github.com/go-json-experiment/json/doc.go
generated
vendored
96
vendor/github.com/go-json-experiment/json/doc.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
// Package json implements semantic processing of JSON as specified in RFC 8259.
|
||||
// JSON is a simple data interchange format that can represent
|
||||
// primitive data types such as booleans, strings, and numbers,
|
||||
@@ -159,6 +161,100 @@
|
||||
// Marshaling or unmarshaling a non-empty struct
|
||||
// without any JSON representable fields results in a [SemanticError].
|
||||
// Unexported fields must not have any `json` tags except for `json:"-"`.
|
||||
//
|
||||
// # Security Considerations
|
||||
//
|
||||
// JSON is frequently used as a data interchange format to communicate
|
||||
// between different systems, possibly implemented in different languages.
|
||||
// For interoperability and security reasons, it is important that
|
||||
// all implementations agree upon the semantic meaning of the data.
|
||||
//
|
||||
// [For example, suppose we have two micro-services.]
|
||||
// The first service is responsible for authenticating a JSON request,
|
||||
// while the second service is responsible for executing the request
|
||||
// (having assumed that the prior service authenticated the request).
|
||||
// If an attacker were able to maliciously craft a JSON request such that
|
||||
// both services believe that the same request is from different users,
|
||||
// it could bypass the authenticator with valid credentials for one user,
|
||||
// but maliciously perform an action on behalf of a different user.
|
||||
//
|
||||
// According to RFC 8259, there unfortunately exist many JSON texts
|
||||
// that are syntactically valid but semantically ambiguous.
|
||||
// For example, the standard does not define how to interpret duplicate
|
||||
// names within an object.
|
||||
//
|
||||
// The v1 [encoding/json] and [encoding/json/v2] packages
|
||||
// interpret some inputs in different ways. In particular:
|
||||
//
|
||||
// - The standard specifies that JSON must be encoded using UTF-8.
|
||||
// By default, v1 replaces invalid bytes of UTF-8 in JSON strings
|
||||
// with the Unicode replacement character,
|
||||
// while v2 rejects inputs with invalid UTF-8.
|
||||
// To change the default, specify the [jsontext.AllowInvalidUTF8] option.
|
||||
// The replacement of invalid UTF-8 is a form of data corruption
|
||||
// that alters the precise meaning of strings.
|
||||
//
|
||||
// - The standard does not specify a particular behavior when
|
||||
// duplicate names are encountered within a JSON object,
|
||||
// which means that different implementations may behave differently.
|
||||
// By default, v1 allows for the presence of duplicate names,
|
||||
// while v2 rejects duplicate names.
|
||||
// To change the default, specify the [jsontext.AllowDuplicateNames] option.
|
||||
// If allowed, object members are processed in the order they are observed,
|
||||
// meaning that later values will replace or be merged into prior values,
|
||||
// depending on the Go value type.
|
||||
//
|
||||
// - The standard defines a JSON object as an unordered collection of name/value pairs.
|
||||
// While ordering can be observed through the underlying [jsontext] API,
|
||||
// both v1 and v2 generally avoid exposing the ordering.
|
||||
// No application should semantically depend on the order of object members.
|
||||
// Allowing duplicate names is a vector through which ordering of members
|
||||
// can accidentally be observed and depended upon.
|
||||
//
|
||||
// - The standard suggests that JSON object names are typically compared
|
||||
// based on equality of the sequence of Unicode code points,
|
||||
// which implies that comparing names is often case-sensitive.
|
||||
// When unmarshaling a JSON object into a Go struct,
|
||||
// by default, v1 uses a (loose) case-insensitive match on the name,
|
||||
// while v2 uses a (strict) case-sensitive match on the name.
|
||||
// To change the default, specify the [MatchCaseInsensitiveNames] option.
|
||||
// The use of case-insensitive matching provides another vector through
|
||||
// which duplicate names can occur. Allowing case-insensitive matching
|
||||
// means that v1 or v2 might interpret JSON objects differently from most
|
||||
// other JSON implementations (which typically use a case-sensitive match).
|
||||
//
|
||||
// - The standard does not specify a particular behavior when
|
||||
// an unknown name in a JSON object is encountered.
|
||||
// When unmarshaling a JSON object into a Go struct, by default
|
||||
// both v1 and v2 ignore unknown names and their corresponding values.
|
||||
// To change the default, specify the [RejectUnknownMembers] option.
|
||||
//
|
||||
// - The standard suggests that implementations may use a float64
|
||||
// to represent a JSON number. Consequently, large JSON integers
|
||||
// may lose precision when stored as a floating-point type.
|
||||
// Both v1 and v2 correctly preserve precision when marshaling and
|
||||
// unmarshaling a concrete integer type. However, even if v1 and v2
|
||||
// preserve precision for concrete types, other JSON implementations
|
||||
// may not be able to preserve precision for outputs produced by v1 or v2.
|
||||
// The `string` tag option can be used to specify that an integer type
|
||||
// is to be quoted within a JSON string to avoid loss of precision.
|
||||
// Furthermore, v1 and v2 may still lose precision when unmarshaling
|
||||
// into an any interface value, where unmarshal uses a float64
|
||||
// by default to represent a JSON number.
|
||||
// To change the default, specify the [WithUnmarshalers] option
|
||||
// with a custom unmarshaler that pre-populates the interface value
|
||||
// with a concrete Go type that can preserve precision.
|
||||
//
|
||||
// RFC 8785 specifies a canonical form for any JSON text,
|
||||
// which explicitly defines specific behaviors that RFC 8259 leaves undefined.
|
||||
// In theory, if a text can successfully [jsontext.Value.Canonicalize]
|
||||
// without changing the semantic meaning of the data, then it provides a
|
||||
// greater degree of confidence that the data is more secure and interoperable.
|
||||
//
|
||||
// The v2 API generally chooses more secure defaults than v1,
|
||||
// but care should still be taken with large integers or unknown members.
|
||||
//
|
||||
// [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s
|
||||
package json
|
||||
|
||||
// requireKeyedLiterals can be embedded in a struct to require keyed literals.
|
||||
|
||||
11
vendor/github.com/go-json-experiment/json/errors.go
generated
vendored
11
vendor/github.com/go-json-experiment/json/errors.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
@@ -118,10 +120,17 @@ func newMarshalErrorBefore(e *jsontext.Encoder, t reflect.Type, err error) error
|
||||
// is positioned right before the next token or value, which causes an error.
|
||||
// It does not record the next JSON kind as this error is used to indicate
|
||||
// the receiving Go value is invalid to unmarshal into (and not a JSON error).
|
||||
// However, if [jsonflags.ReportErrorsWithLegacySemantics] is specified,
|
||||
// then it does record the next JSON kind for historical reporting reasons.
|
||||
func newUnmarshalErrorBefore(d *jsontext.Decoder, t reflect.Type, err error) error {
|
||||
var k jsontext.Kind
|
||||
if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
|
||||
k = d.PeekKind()
|
||||
}
|
||||
return &SemanticError{action: "unmarshal", GoType: t, Err: err,
|
||||
ByteOffset: d.InputOffset() + int64(export.Decoder(d).CountNextDelimWhitespace()),
|
||||
JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, +1))}
|
||||
JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, +1)),
|
||||
JSONKind: k}
|
||||
}
|
||||
|
||||
// newUnmarshalErrorBeforeWithSkipping is like [newUnmarshalErrorBefore],
|
||||
|
||||
10
vendor/github.com/go-json-experiment/json/fields.go
generated
vendored
10
vendor/github.com/go-json-experiment/json/fields.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
@@ -402,6 +404,7 @@ type fieldOptions struct {
|
||||
// the JSON member name and other features.
|
||||
func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, err error) {
|
||||
tag, hasTag := sf.Tag.Lookup("json")
|
||||
tagOrig := tag
|
||||
|
||||
// Check whether this field is explicitly ignored.
|
||||
if tag == "-" {
|
||||
@@ -451,6 +454,13 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool,
|
||||
err = cmp.Or(err, fmt.Errorf("Go struct field %s has JSON object name %q with invalid UTF-8", sf.Name, name))
|
||||
name = string([]rune(name)) // replace invalid UTF-8 with utf8.RuneError
|
||||
}
|
||||
if name == "-" && tag[0] == '-' {
|
||||
defer func() { // defer to let other errors take precedence
|
||||
err = cmp.Or(err, fmt.Errorf("Go struct field %s has JSON object name %q; either "+
|
||||
"use `json:\"-\"` to ignore the field or "+
|
||||
"use `json:\"'-'%s` to specify %q as the name", sf.Name, out.name, strings.TrimPrefix(strconv.Quote(tagOrig), `"-`), name))
|
||||
}()
|
||||
}
|
||||
if err2 == nil {
|
||||
out.hasName = true
|
||||
out.name = name
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/fold.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/fold.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/intern.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/intern.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
|
||||
3
vendor/github.com/go-json-experiment/json/internal/internal.go
generated
vendored
3
vendor/github.com/go-json-experiment/json/internal/internal.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package internal
|
||||
|
||||
import "errors"
|
||||
@@ -19,6 +21,7 @@ var AllowInternalUse NotForPublicUse
|
||||
var (
|
||||
ErrCycle = errors.New("encountered a cycle")
|
||||
ErrNonNilReference = errors.New("value must be passed as a non-nil pointer reference")
|
||||
ErrNilInterface = errors.New("cannot derive concrete type for nil interface with finite type set")
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
26
vendor/github.com/go-json-experiment/json/internal/jsonflags/flags.go
generated
vendored
26
vendor/github.com/go-json-experiment/json/internal/jsonflags/flags.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
// jsonflags implements all the optional boolean flags.
|
||||
// These flags are shared across both "json", "jsontext", and "jsonopts".
|
||||
package jsonflags
|
||||
@@ -50,18 +52,20 @@ const (
|
||||
AllowInvalidUTF8 |
|
||||
EscapeForHTML |
|
||||
EscapeForJS |
|
||||
EscapeInvalidUTF8 |
|
||||
PreserveRawStrings |
|
||||
Deterministic |
|
||||
FormatNilMapAsNull |
|
||||
FormatNilSliceAsNull |
|
||||
MatchCaseInsensitiveNames |
|
||||
CallMethodsWithLegacySemantics |
|
||||
FormatByteArrayAsArray |
|
||||
FormatBytesWithLegacySemantics |
|
||||
FormatTimeWithLegacySemantics |
|
||||
FormatDurationAsNano |
|
||||
MatchCaseSensitiveDelimiter |
|
||||
MergeWithLegacySemantics |
|
||||
OmitEmptyWithLegacyDefinition |
|
||||
OmitEmptyWithLegacySemantics |
|
||||
ParseBytesWithLooseRFC4648 |
|
||||
ParseTimeWithLooseRFC3339 |
|
||||
ReportErrorsWithLegacySemantics |
|
||||
StringifyWithLegacySemantics |
|
||||
UnmarshalArrayFromAnyLength
|
||||
@@ -75,7 +79,7 @@ const (
|
||||
WhitespaceFlags = AnyWhitespace | Indent | IndentPrefix
|
||||
|
||||
// AnyEscape is the set of flags related to escaping in a JSON string.
|
||||
AnyEscape = EscapeForHTML | EscapeForJS | EscapeInvalidUTF8
|
||||
AnyEscape = EscapeForHTML | EscapeForJS
|
||||
|
||||
// CanonicalizeNumbers is the set of flags related to raw number canonicalization.
|
||||
CanonicalizeNumbers = CanonicalizeRawInts | CanonicalizeRawFloats
|
||||
@@ -95,7 +99,6 @@ const (
|
||||
ReorderRawObjects // encode only
|
||||
EscapeForHTML // encode only
|
||||
EscapeForJS // encode only
|
||||
EscapeInvalidUTF8 // encode only; only exposed in v1
|
||||
Multiline // encode only
|
||||
SpaceAfterColon // encode only
|
||||
SpaceAfterComma // encode only
|
||||
@@ -130,11 +133,14 @@ const (
|
||||
_ Bools = (maxArshalV2Flag >> 1) << iota
|
||||
|
||||
CallMethodsWithLegacySemantics // marshal or unmarshal
|
||||
FormatByteArrayAsArray // marshal or unmarshal
|
||||
FormatBytesWithLegacySemantics // marshal or unmarshal
|
||||
FormatTimeWithLegacySemantics // marshal or unmarshal
|
||||
FormatDurationAsNano // marshal or unmarshal
|
||||
MatchCaseSensitiveDelimiter // marshal or unmarshal
|
||||
MergeWithLegacySemantics // unmarshal
|
||||
OmitEmptyWithLegacyDefinition // marshal
|
||||
OmitEmptyWithLegacySemantics // marshal
|
||||
ParseBytesWithLooseRFC4648 // unmarshal
|
||||
ParseTimeWithLooseRFC3339 // unmarshal
|
||||
ReportErrorsWithLegacySemantics // marshal or unmarshal
|
||||
StringifyWithLegacySemantics // marshal or unmarshal
|
||||
StringifyBoolsAndStrings // marshal or unmarshal; for internal use by jsonv2.makeStructArshaler
|
||||
@@ -144,6 +150,12 @@ const (
|
||||
maxArshalV1Flag
|
||||
)
|
||||
|
||||
// bitsUsed is the number of bits used in the 64-bit boolean flags
|
||||
const bitsUsed = 42
|
||||
|
||||
// Static compile check that bitsUsed and maxArshalV1Flag are in sync.
|
||||
const _ = uint64((1<<bitsUsed)-maxArshalV1Flag) + uint64(maxArshalV1Flag-(1<<bitsUsed))
|
||||
|
||||
// Flags is a set of boolean flags.
|
||||
// If the presence bit is zero, then the value bit must also be zero.
|
||||
// The least-significant bit of both fields is always zero.
|
||||
|
||||
10
vendor/github.com/go-json-experiment/json/internal/jsonopts/options.go
generated
vendored
10
vendor/github.com/go-json-experiment/json/internal/jsonopts/options.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsonopts
|
||||
|
||||
import (
|
||||
@@ -63,7 +65,7 @@ func (*Struct) JSONOptions(internal.NotForPublicUse) {}
|
||||
|
||||
// GetUnknownOption is injected by the "json" package to handle Options
|
||||
// declared in that package so that "jsonopts" can handle them.
|
||||
var GetUnknownOption = func(*Struct, Options) (any, bool) { panic("unknown option") }
|
||||
var GetUnknownOption = func(Struct, Options) (any, bool) { panic("unknown option") }
|
||||
|
||||
func GetOption[T any](opts Options, setter func(T) Options) (T, bool) {
|
||||
// Collapse the options to *Struct to simplify lookup.
|
||||
@@ -102,14 +104,14 @@ func GetOption[T any](opts Options, setter func(T) Options) (T, bool) {
|
||||
}
|
||||
return any(structOpts.DepthLimit).(T), true
|
||||
default:
|
||||
v, ok := GetUnknownOption(structOpts, opt)
|
||||
v, ok := GetUnknownOption(*structOpts, opt)
|
||||
return v.(T), ok
|
||||
}
|
||||
}
|
||||
|
||||
// JoinUnknownOption is injected by the "json" package to handle Options
|
||||
// declared in that package so that "jsonopts" can handle them.
|
||||
var JoinUnknownOption = func(*Struct, Options) { panic("unknown option") }
|
||||
var JoinUnknownOption = func(Struct, Options) Struct { panic("unknown option") }
|
||||
|
||||
func (dst *Struct) Join(srcs ...Options) {
|
||||
dst.join(false, srcs...)
|
||||
@@ -180,7 +182,7 @@ func (dst *Struct) join(excludeCoderOptions bool, srcs ...Options) {
|
||||
}
|
||||
}
|
||||
default:
|
||||
JoinUnknownOption(dst, src)
|
||||
*dst = JoinUnknownOption(*dst, src)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/internal/jsonwire/decode.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/internal/jsonwire/decode.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsonwire
|
||||
|
||||
import (
|
||||
|
||||
8
vendor/github.com/go-json-experiment/json/internal/jsonwire/encode.go
generated
vendored
8
vendor/github.com/go-json-experiment/json/internal/jsonwire/encode.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsonwire
|
||||
|
||||
import (
|
||||
@@ -90,11 +92,7 @@ func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes, flags *jsonflag
|
||||
case isInvalidUTF8(r, rn):
|
||||
hasInvalidUTF8 = true
|
||||
dst = append(dst, src[i:n-rn]...)
|
||||
if flags.Get(jsonflags.EscapeInvalidUTF8) {
|
||||
dst = append(dst, `\ufffd`...)
|
||||
} else {
|
||||
dst = append(dst, "\ufffd"...)
|
||||
}
|
||||
dst = append(dst, "\ufffd"...)
|
||||
i = n
|
||||
case (r == '\u2028' || r == '\u2029') && flags.Get(jsonflags.EscapeForJS):
|
||||
dst = append(dst, src[i:n-rn]...)
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/internal/jsonwire/wire.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/internal/jsonwire/wire.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
// Package jsonwire implements stateless functionality for handling JSON text.
|
||||
package jsonwire
|
||||
|
||||
|
||||
536
vendor/github.com/go-json-experiment/json/jsontext/alias.go
generated
vendored
Normal file
536
vendor/github.com/go-json-experiment/json/jsontext/alias.go
generated
vendored
Normal file
@@ -0,0 +1,536 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
// Code generated by alias_gen.go; DO NOT EDIT.
|
||||
|
||||
//go:build goexperiment.jsonv2 && go1.25
|
||||
|
||||
// Package jsontext implements syntactic processing of JSON
|
||||
// as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785.
|
||||
// JSON is a simple data interchange format that can represent
|
||||
// primitive data types such as booleans, strings, and numbers,
|
||||
// in addition to structured data types such as objects and arrays.
|
||||
//
|
||||
// The [Encoder] and [Decoder] types are used to encode or decode
|
||||
// a stream of JSON tokens or values.
|
||||
//
|
||||
// # Tokens and Values
|
||||
//
|
||||
// A JSON token refers to the basic structural elements of JSON:
|
||||
//
|
||||
// - a JSON literal (i.e., null, true, or false)
|
||||
// - a JSON string (e.g., "hello, world!")
|
||||
// - a JSON number (e.g., 123.456)
|
||||
// - a begin or end delimiter for a JSON object (i.e., '{' or '}')
|
||||
// - a begin or end delimiter for a JSON array (i.e., '[' or ']')
|
||||
//
|
||||
// A JSON token is represented by the [Token] type in Go. Technically,
|
||||
// there are two additional structural characters (i.e., ':' and ','),
|
||||
// but there is no [Token] representation for them since their presence
|
||||
// can be inferred by the structure of the JSON grammar itself.
|
||||
// For example, there must always be an implicit colon between
|
||||
// the name and value of a JSON object member.
|
||||
//
|
||||
// A JSON value refers to a complete unit of JSON data:
|
||||
//
|
||||
// - a JSON literal, string, or number
|
||||
// - a JSON object (e.g., `{"name":"value"}`)
|
||||
// - a JSON array (e.g., `[1,2,3,]`)
|
||||
//
|
||||
// A JSON value is represented by the [Value] type in Go and is a []byte
|
||||
// containing the raw textual representation of the value. There is some overlap
|
||||
// between tokens and values as both contain literals, strings, and numbers.
|
||||
// However, only a value can represent the entirety of a JSON object or array.
|
||||
//
|
||||
// The [Encoder] and [Decoder] types contain methods to read or write the next
|
||||
// [Token] or [Value] in a sequence. They maintain a state machine to validate
|
||||
// whether the sequence of JSON tokens and/or values produces a valid JSON.
|
||||
// [Options] may be passed to the [NewEncoder] or [NewDecoder] constructors
|
||||
// to configure the syntactic behavior of encoding and decoding.
|
||||
//
|
||||
// # Terminology
|
||||
//
|
||||
// The terms "encode" and "decode" are used for syntactic functionality
|
||||
// that is concerned with processing JSON based on its grammar, and
|
||||
// the terms "marshal" and "unmarshal" are used for semantic functionality
|
||||
// that determines the meaning of JSON values as Go values and vice-versa.
|
||||
// This package (i.e., [jsontext]) deals with JSON at a syntactic layer,
|
||||
// while [encoding/json/v2] deals with JSON at a semantic layer.
|
||||
// The goal is to provide a clear distinction between functionality that
|
||||
// is purely concerned with encoding versus that of marshaling.
|
||||
// For example, one can directly encode a stream of JSON tokens without
|
||||
// needing to marshal a concrete Go value representing them.
|
||||
// Similarly, one can decode a stream of JSON tokens without
|
||||
// needing to unmarshal them into a concrete Go value.
|
||||
//
|
||||
// This package uses JSON terminology when discussing JSON, which may differ
|
||||
// from related concepts in Go or elsewhere in computing literature.
|
||||
//
|
||||
// - a JSON "object" refers to an unordered collection of name/value members.
|
||||
// - a JSON "array" refers to an ordered sequence of elements.
|
||||
// - a JSON "value" refers to either a literal (i.e., null, false, or true),
|
||||
// string, number, object, or array.
|
||||
//
|
||||
// See RFC 8259 for more information.
|
||||
//
|
||||
// # Specifications
|
||||
//
|
||||
// Relevant specifications include RFC 4627, RFC 7159, RFC 7493, RFC 8259,
|
||||
// and RFC 8785. Each RFC is generally a stricter subset of another RFC.
|
||||
// In increasing order of strictness:
|
||||
//
|
||||
// - RFC 4627 and RFC 7159 do not require (but recommend) the use of UTF-8
|
||||
// and also do not require (but recommend) that object names be unique.
|
||||
// - RFC 8259 requires the use of UTF-8,
|
||||
// but does not require (but recommends) that object names be unique.
|
||||
// - RFC 7493 requires the use of UTF-8
|
||||
// and also requires that object names be unique.
|
||||
// - RFC 8785 defines a canonical representation. It requires the use of UTF-8
|
||||
// and also requires that object names be unique and in a specific ordering.
|
||||
// It specifies exactly how strings and numbers must be formatted.
|
||||
//
|
||||
// The primary difference between RFC 4627 and RFC 7159 is that the former
|
||||
// restricted top-level values to only JSON objects and arrays, while
|
||||
// RFC 7159 and subsequent RFCs permit top-level values to additionally be
|
||||
// JSON nulls, booleans, strings, or numbers.
|
||||
//
|
||||
// By default, this package operates on RFC 7493, but can be configured
|
||||
// to operate according to the other RFC specifications.
|
||||
// RFC 7493 is a stricter subset of RFC 8259 and fully compliant with it.
|
||||
// In particular, it makes specific choices about behavior that RFC 8259
|
||||
// leaves as undefined in order to ensure greater interoperability.
|
||||
//
|
||||
// # Security Considerations
|
||||
//
|
||||
// See the "Security Considerations" section in [encoding/json/v2].
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
"encoding/json/jsontext"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Decoder is a streaming decoder for raw JSON tokens and values.
|
||||
// It is used to read a stream of top-level JSON values,
|
||||
// each separated by optional whitespace characters.
|
||||
//
|
||||
// [Decoder.ReadToken] and [Decoder.ReadValue] calls may be interleaved.
|
||||
// For example, the following JSON value:
|
||||
//
|
||||
// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}}
|
||||
//
|
||||
// can be parsed with the following calls (ignoring errors for brevity):
|
||||
//
|
||||
// d.ReadToken() // {
|
||||
// d.ReadToken() // "name"
|
||||
// d.ReadToken() // "value"
|
||||
// d.ReadValue() // "array"
|
||||
// d.ReadToken() // [
|
||||
// d.ReadToken() // null
|
||||
// d.ReadToken() // false
|
||||
// d.ReadValue() // true
|
||||
// d.ReadToken() // 3.14159
|
||||
// d.ReadToken() // ]
|
||||
// d.ReadValue() // "object"
|
||||
// d.ReadValue() // {"k":"v"}
|
||||
// d.ReadToken() // }
|
||||
//
|
||||
// The above is one of many possible sequence of calls and
|
||||
// may not represent the most sensible method to call for any given token/value.
|
||||
// For example, it is probably more common to call [Decoder.ReadToken] to obtain a
|
||||
// string token for object names.
|
||||
type Decoder = jsontext.Decoder
|
||||
|
||||
// NewDecoder constructs a new streaming decoder reading from r.
|
||||
//
|
||||
// If r is a [bytes.Buffer], then the decoder parses directly from the buffer
|
||||
// without first copying the contents to an intermediate buffer.
|
||||
// Additional writes to the buffer must not occur while the decoder is in use.
|
||||
func NewDecoder(r io.Reader, opts ...Options) *Decoder {
|
||||
return jsontext.NewDecoder(r, opts...)
|
||||
}
|
||||
|
||||
// Encoder is a streaming encoder from raw JSON tokens and values.
|
||||
// It is used to write a stream of top-level JSON values,
|
||||
// each terminated with a newline character.
|
||||
//
|
||||
// [Encoder.WriteToken] and [Encoder.WriteValue] calls may be interleaved.
|
||||
// For example, the following JSON value:
|
||||
//
|
||||
// {"name":"value","array":[null,false,true,3.14159],"object":{"k":"v"}}
|
||||
//
|
||||
// can be composed with the following calls (ignoring errors for brevity):
|
||||
//
|
||||
// e.WriteToken(BeginObject) // {
|
||||
// e.WriteToken(String("name")) // "name"
|
||||
// e.WriteToken(String("value")) // "value"
|
||||
// e.WriteValue(Value(`"array"`)) // "array"
|
||||
// e.WriteToken(BeginArray) // [
|
||||
// e.WriteToken(Null) // null
|
||||
// e.WriteToken(False) // false
|
||||
// e.WriteValue(Value("true")) // true
|
||||
// e.WriteToken(Float(3.14159)) // 3.14159
|
||||
// e.WriteToken(EndArray) // ]
|
||||
// e.WriteValue(Value(`"object"`)) // "object"
|
||||
// e.WriteValue(Value(`{"k":"v"}`)) // {"k":"v"}
|
||||
// e.WriteToken(EndObject) // }
|
||||
//
|
||||
// The above is one of many possible sequence of calls and
|
||||
// may not represent the most sensible method to call for any given token/value.
|
||||
// For example, it is probably more common to call [Encoder.WriteToken] with a string
|
||||
// for object names.
|
||||
type Encoder = jsontext.Encoder
|
||||
|
||||
// NewEncoder constructs a new streaming encoder writing to w
|
||||
// configured with the provided options.
|
||||
// It flushes the internal buffer when the buffer is sufficiently full or
|
||||
// when a top-level value has been written.
|
||||
//
|
||||
// If w is a [bytes.Buffer], then the encoder appends directly into the buffer
|
||||
// without copying the contents from an intermediate buffer.
|
||||
func NewEncoder(w io.Writer, opts ...Options) *Encoder {
|
||||
return jsontext.NewEncoder(w, opts...)
|
||||
}
|
||||
|
||||
// SyntacticError is a description of a syntactic error that occurred when
|
||||
// encoding or decoding JSON according to the grammar.
|
||||
//
|
||||
// The contents of this error as produced by this package may change over time.
|
||||
type SyntacticError = jsontext.SyntacticError
|
||||
|
||||
// Options configures [NewEncoder], [Encoder.Reset], [NewDecoder],
|
||||
// and [Decoder.Reset] with specific features.
|
||||
// Each function takes in a variadic list of options, where properties
|
||||
// set in latter options override the value of previously set properties.
|
||||
//
|
||||
// There is a single Options type, which is used with both encoding and decoding.
|
||||
// Some options affect both operations, while others only affect one operation:
|
||||
//
|
||||
// - [AllowDuplicateNames] affects encoding and decoding
|
||||
// - [AllowInvalidUTF8] affects encoding and decoding
|
||||
// - [EscapeForHTML] affects encoding only
|
||||
// - [EscapeForJS] affects encoding only
|
||||
// - [PreserveRawStrings] affects encoding only
|
||||
// - [CanonicalizeRawInts] affects encoding only
|
||||
// - [CanonicalizeRawFloats] affects encoding only
|
||||
// - [ReorderRawObjects] affects encoding only
|
||||
// - [SpaceAfterColon] affects encoding only
|
||||
// - [SpaceAfterComma] affects encoding only
|
||||
// - [Multiline] affects encoding only
|
||||
// - [WithIndent] affects encoding only
|
||||
// - [WithIndentPrefix] affects encoding only
|
||||
//
|
||||
// Options that do not affect a particular operation are ignored.
|
||||
//
|
||||
// The Options type is identical to [encoding/json.Options] and
|
||||
// [encoding/json/v2.Options]. Options from the other packages may
|
||||
// be passed to functionality in this package, but are ignored.
|
||||
// Options from this package may be used with the other packages.
|
||||
type Options = jsontext.Options
|
||||
|
||||
// AllowDuplicateNames specifies that JSON objects may contain
|
||||
// duplicate member names. Disabling the duplicate name check may provide
|
||||
// performance benefits, but breaks compliance with RFC 7493, section 2.3.
|
||||
// The input or output will still be compliant with RFC 8259,
|
||||
// which leaves the handling of duplicate names as unspecified behavior.
|
||||
//
|
||||
// This affects either encoding or decoding.
|
||||
func AllowDuplicateNames(v bool) Options {
|
||||
return jsontext.AllowDuplicateNames(v)
|
||||
}
|
||||
|
||||
// AllowInvalidUTF8 specifies that JSON strings may contain invalid UTF-8,
|
||||
// which will be mangled as the Unicode replacement character, U+FFFD.
|
||||
// This causes the encoder or decoder to break compliance with
|
||||
// RFC 7493, section 2.1, and RFC 8259, section 8.1.
|
||||
//
|
||||
// This affects either encoding or decoding.
|
||||
func AllowInvalidUTF8(v bool) Options {
|
||||
return jsontext.AllowInvalidUTF8(v)
|
||||
}
|
||||
|
||||
// EscapeForHTML specifies that '<', '>', and '&' characters within JSON strings
|
||||
// should be escaped as a hexadecimal Unicode codepoint (e.g., \u003c) so that
|
||||
// the output is safe to embed within HTML.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func EscapeForHTML(v bool) Options {
|
||||
return jsontext.EscapeForHTML(v)
|
||||
}
|
||||
|
||||
// EscapeForJS specifies that U+2028 and U+2029 characters within JSON strings
|
||||
// should be escaped as a hexadecimal Unicode codepoint (e.g., \u2028) so that
|
||||
// the output is valid to embed within JavaScript. See RFC 8259, section 12.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func EscapeForJS(v bool) Options {
|
||||
return jsontext.EscapeForJS(v)
|
||||
}
|
||||
|
||||
// PreserveRawStrings specifies that when encoding a raw JSON string in a
|
||||
// [Token] or [Value], pre-escaped sequences
|
||||
// in a JSON string are preserved to the output.
|
||||
// However, raw strings still respect [EscapeForHTML] and [EscapeForJS]
|
||||
// such that the relevant characters are escaped.
|
||||
// If [AllowInvalidUTF8] is enabled, bytes of invalid UTF-8
|
||||
// are preserved to the output.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func PreserveRawStrings(v bool) Options {
|
||||
return jsontext.PreserveRawStrings(v)
|
||||
}
|
||||
|
||||
// CanonicalizeRawInts specifies that when encoding a raw JSON
|
||||
// integer number (i.e., a number without a fraction and exponent) in a
|
||||
// [Token] or [Value], the number is canonicalized
|
||||
// according to RFC 8785, section 3.2.2.3. As a special case,
|
||||
// the number -0 is canonicalized as 0.
|
||||
//
|
||||
// JSON numbers are treated as IEEE 754 double precision numbers.
|
||||
// Any numbers with precision beyond what is representable by that form
|
||||
// will lose their precision when canonicalized. For example,
|
||||
// integer values beyond ±2⁵³ will lose their precision.
|
||||
// For example, 1234567890123456789 is formatted as 1234567890123456800.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func CanonicalizeRawInts(v bool) Options {
|
||||
return jsontext.CanonicalizeRawInts(v)
|
||||
}
|
||||
|
||||
// CanonicalizeRawFloats specifies that when encoding a raw JSON
|
||||
// floating-point number (i.e., a number with a fraction or exponent) in a
|
||||
// [Token] or [Value], the number is canonicalized
|
||||
// according to RFC 8785, section 3.2.2.3. As a special case,
|
||||
// the number -0 is canonicalized as 0.
|
||||
//
|
||||
// JSON numbers are treated as IEEE 754 double precision numbers.
|
||||
// It is safe to canonicalize a serialized single precision number and
|
||||
// parse it back as a single precision number and expect the same value.
|
||||
// If a number exceeds ±1.7976931348623157e+308, which is the maximum
|
||||
// finite number, then it saturated at that value and formatted as such.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func CanonicalizeRawFloats(v bool) Options {
|
||||
return jsontext.CanonicalizeRawFloats(v)
|
||||
}
|
||||
|
||||
// ReorderRawObjects specifies that when encoding a raw JSON object in a
|
||||
// [Value], the object members are reordered according to
|
||||
// RFC 8785, section 3.2.3.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func ReorderRawObjects(v bool) Options {
|
||||
return jsontext.ReorderRawObjects(v)
|
||||
}
|
||||
|
||||
// SpaceAfterColon specifies that the JSON output should emit a space character
|
||||
// after each colon separator following a JSON object name.
|
||||
// If false, then no space character appears after the colon separator.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func SpaceAfterColon(v bool) Options {
|
||||
return jsontext.SpaceAfterColon(v)
|
||||
}
|
||||
|
||||
// SpaceAfterComma specifies that the JSON output should emit a space character
|
||||
// after each comma separator following a JSON object value or array element.
|
||||
// If false, then no space character appears after the comma separator.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func SpaceAfterComma(v bool) Options {
|
||||
return jsontext.SpaceAfterComma(v)
|
||||
}
|
||||
|
||||
// Multiline specifies that the JSON output should expand to multiple lines,
|
||||
// where every JSON object member or JSON array element appears on
|
||||
// a new, indented line according to the nesting depth.
|
||||
//
|
||||
// If [SpaceAfterColon] is not specified, then the default is true.
|
||||
// If [SpaceAfterComma] is not specified, then the default is false.
|
||||
// If [WithIndent] is not specified, then the default is "\t".
|
||||
//
|
||||
// If set to false, then the output is a single-line,
|
||||
// where the only whitespace emitted is determined by the current
|
||||
// values of [SpaceAfterColon] and [SpaceAfterComma].
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
func Multiline(v bool) Options {
|
||||
return jsontext.Multiline(v)
|
||||
}
|
||||
|
||||
// WithIndent specifies that the encoder should emit multiline output
|
||||
// where each element in a JSON object or array begins on a new, indented line
|
||||
// beginning with the indent prefix (see [WithIndentPrefix])
|
||||
// followed by one or more copies of indent according to the nesting depth.
|
||||
// The indent must only be composed of space or tab characters.
|
||||
//
|
||||
// If the intent to emit indented output without a preference for
|
||||
// the particular indent string, then use [Multiline] instead.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
// Use of this option implies [Multiline] being set to true.
|
||||
func WithIndent(indent string) Options {
|
||||
return jsontext.WithIndent(indent)
|
||||
}
|
||||
|
||||
// WithIndentPrefix specifies that the encoder should emit multiline output
|
||||
// where each element in a JSON object or array begins on a new, indented line
|
||||
// beginning with the indent prefix followed by one or more copies of indent
|
||||
// (see [WithIndent]) according to the nesting depth.
|
||||
// The prefix must only be composed of space or tab characters.
|
||||
//
|
||||
// This only affects encoding and is ignored when decoding.
|
||||
// Use of this option implies [Multiline] being set to true.
|
||||
func WithIndentPrefix(prefix string) Options {
|
||||
return jsontext.WithIndentPrefix(prefix)
|
||||
}
|
||||
|
||||
// AppendQuote appends a double-quoted JSON string literal representing src
|
||||
// to dst and returns the extended buffer.
|
||||
// It uses the minimal string representation per RFC 8785, section 3.2.2.2.
|
||||
// Invalid UTF-8 bytes are replaced with the Unicode replacement character
|
||||
// and an error is returned at the end indicating the presence of invalid UTF-8.
|
||||
// The dst must not overlap with the src.
|
||||
func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) {
|
||||
return jsontext.AppendQuote[Bytes](dst, src)
|
||||
}
|
||||
|
||||
// AppendUnquote appends the decoded interpretation of src as a
|
||||
// double-quoted JSON string literal to dst and returns the extended buffer.
|
||||
// The input src must be a JSON string without any surrounding whitespace.
|
||||
// Invalid UTF-8 bytes are replaced with the Unicode replacement character
|
||||
// and an error is returned at the end indicating the presence of invalid UTF-8.
|
||||
// Any trailing bytes after the JSON string literal results in an error.
|
||||
// The dst must not overlap with the src.
|
||||
func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) {
|
||||
return jsontext.AppendUnquote[Bytes](dst, src)
|
||||
}
|
||||
|
||||
// ErrDuplicateName indicates that a JSON token could not be
|
||||
// encoded or decoded because it results in a duplicate JSON object name.
|
||||
// This error is directly wrapped within a [SyntacticError] when produced.
|
||||
//
|
||||
// The name of a duplicate JSON object member can be extracted as:
|
||||
//
|
||||
// err := ...
|
||||
// var serr jsontext.SyntacticError
|
||||
// if errors.As(err, &serr) && serr.Err == jsontext.ErrDuplicateName {
|
||||
// ptr := serr.JSONPointer // JSON pointer to duplicate name
|
||||
// name := ptr.LastToken() // duplicate name itself
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// This error is only returned if [AllowDuplicateNames] is false.
|
||||
var ErrDuplicateName = jsontext.ErrDuplicateName
|
||||
|
||||
// ErrNonStringName indicates that a JSON token could not be
|
||||
// encoded or decoded because it is not a string,
|
||||
// as required for JSON object names according to RFC 8259, section 4.
|
||||
// This error is directly wrapped within a [SyntacticError] when produced.
|
||||
var ErrNonStringName = jsontext.ErrNonStringName
|
||||
|
||||
// Pointer is a JSON Pointer (RFC 6901) that references a particular JSON value
|
||||
// relative to the root of the top-level JSON value.
|
||||
//
|
||||
// A Pointer is a slash-separated list of tokens, where each token is
|
||||
// either a JSON object name or an index to a JSON array element
|
||||
// encoded as a base-10 integer value.
|
||||
// It is impossible to distinguish between an array index and an object name
|
||||
// (that happens to be an base-10 encoded integer) without also knowing
|
||||
// the structure of the top-level JSON value that the pointer refers to.
|
||||
//
|
||||
// There is exactly one representation of a pointer to a particular value,
|
||||
// so comparability of Pointer values is equivalent to checking whether
|
||||
// they both point to the exact same value.
|
||||
type Pointer = jsontext.Pointer
|
||||
|
||||
// Token represents a lexical JSON token, which may be one of the following:
|
||||
// - a JSON literal (i.e., null, true, or false)
|
||||
// - a JSON string (e.g., "hello, world!")
|
||||
// - a JSON number (e.g., 123.456)
|
||||
// - a begin or end delimiter for a JSON object (i.e., { or } )
|
||||
// - a begin or end delimiter for a JSON array (i.e., [ or ] )
|
||||
//
|
||||
// A Token cannot represent entire array or object values, while a [Value] can.
|
||||
// There is no Token to represent commas and colons since
|
||||
// these structural tokens can be inferred from the surrounding context.
|
||||
type Token = jsontext.Token
|
||||
|
||||
var (
|
||||
Null = jsontext.Null
|
||||
False = jsontext.False
|
||||
True = jsontext.True
|
||||
BeginObject = jsontext.BeginObject
|
||||
EndObject = jsontext.EndObject
|
||||
BeginArray = jsontext.BeginArray
|
||||
EndArray = jsontext.EndArray
|
||||
)
|
||||
|
||||
// Bool constructs a Token representing a JSON boolean.
|
||||
func Bool(b bool) Token {
|
||||
return jsontext.Bool(b)
|
||||
}
|
||||
|
||||
// String constructs a Token representing a JSON string.
|
||||
// The provided string should contain valid UTF-8, otherwise invalid characters
|
||||
// may be mangled as the Unicode replacement character.
|
||||
func String(s string) Token {
|
||||
return jsontext.String(s)
|
||||
}
|
||||
|
||||
// Float constructs a Token representing a JSON number.
|
||||
// The values NaN, +Inf, and -Inf will be represented
|
||||
// as a JSON string with the values "NaN", "Infinity", and "-Infinity".
|
||||
func Float(n float64) Token {
|
||||
return jsontext.Float(n)
|
||||
}
|
||||
|
||||
// Int constructs a Token representing a JSON number from an int64.
|
||||
func Int(n int64) Token {
|
||||
return jsontext.Int(n)
|
||||
}
|
||||
|
||||
// Uint constructs a Token representing a JSON number from a uint64.
|
||||
func Uint(n uint64) Token {
|
||||
return jsontext.Uint(n)
|
||||
}
|
||||
|
||||
// Kind represents each possible JSON token kind with a single byte,
|
||||
// which is conveniently the first byte of that kind's grammar
|
||||
// with the restriction that numbers always be represented with '0':
|
||||
//
|
||||
// - 'n': null
|
||||
// - 'f': false
|
||||
// - 't': true
|
||||
// - '"': string
|
||||
// - '0': number
|
||||
// - '{': object begin
|
||||
// - '}': object end
|
||||
// - '[': array begin
|
||||
// - ']': array end
|
||||
//
|
||||
// An invalid kind is usually represented using 0,
|
||||
// but may be non-zero due to invalid JSON data.
|
||||
type Kind = jsontext.Kind
|
||||
|
||||
// AppendFormat formats the JSON value in src and appends it to dst
|
||||
// according to the specified options.
|
||||
// See [Value.Format] for more details about the formatting behavior.
|
||||
//
|
||||
// The dst and src may overlap.
|
||||
// If an error is reported, then the entirety of src is appended to dst.
|
||||
func AppendFormat(dst, src []byte, opts ...Options) ([]byte, error) {
|
||||
return jsontext.AppendFormat(dst, src, opts...)
|
||||
}
|
||||
|
||||
// Value represents a single raw JSON value, which may be one of the following:
|
||||
// - a JSON literal (i.e., null, true, or false)
|
||||
// - a JSON string (e.g., "hello, world!")
|
||||
// - a JSON number (e.g., 123.456)
|
||||
// - an entire JSON object (e.g., {"fizz":"buzz"} )
|
||||
// - an entire JSON array (e.g., [1,2,3] )
|
||||
//
|
||||
// Value can represent entire array or object values, while [Token] cannot.
|
||||
// Value may contain leading and/or trailing whitespace.
|
||||
type Value = jsontext.Value
|
||||
19
vendor/github.com/go-json-experiment/json/jsontext/decode.go
generated
vendored
19
vendor/github.com/go-json-experiment/json/jsontext/decode.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
@@ -136,7 +138,12 @@ func (d *Decoder) Reset(r io.Reader, opts ...Options) {
|
||||
case d.s.Flags.Get(jsonflags.WithinArshalCall):
|
||||
panic("jsontext: cannot reset Decoder passed to json.UnmarshalerFrom")
|
||||
}
|
||||
d.s.reset(nil, r, opts...)
|
||||
// Reuse the buffer if it does not alias a previous [bytes.Buffer].
|
||||
b := d.s.buf[:0]
|
||||
if _, ok := d.s.rd.(*bytes.Buffer); ok {
|
||||
b = nil
|
||||
}
|
||||
d.s.reset(b, r, opts...)
|
||||
}
|
||||
|
||||
func (d *decoderState) reset(b []byte, r io.Reader, opts ...Options) {
|
||||
@@ -767,7 +774,8 @@ func (d *decoderState) ReadValue(flags *jsonwire.ValueFlags) (Value, error) {
|
||||
|
||||
// CheckNextValue checks whether the next value is syntactically valid,
|
||||
// but does not advance the read offset.
|
||||
func (d *decoderState) CheckNextValue() error {
|
||||
// If last, it verifies that the stream cleanly terminates with [io.EOF].
|
||||
func (d *decoderState) CheckNextValue(last bool) error {
|
||||
d.PeekKind() // populates d.peekPos and d.peekErr
|
||||
pos, err := d.peekPos, d.peekErr
|
||||
d.peekPos, d.peekErr = 0, nil
|
||||
@@ -778,13 +786,18 @@ func (d *decoderState) CheckNextValue() error {
|
||||
var flags jsonwire.ValueFlags
|
||||
if pos, err := d.consumeValue(&flags, pos, d.Tokens.Depth()); err != nil {
|
||||
return wrapSyntacticError(d, err, pos, +1)
|
||||
} else if last {
|
||||
return d.checkEOF(pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckEOF verifies that the input has no more data.
|
||||
func (d *decoderState) CheckEOF() error {
|
||||
switch pos, err := d.consumeWhitespace(d.prevEnd); err {
|
||||
return d.checkEOF(d.prevEnd)
|
||||
}
|
||||
func (d *decoderState) checkEOF(pos int) error {
|
||||
switch pos, err := d.consumeWhitespace(pos); err {
|
||||
case nil:
|
||||
err := jsonwire.NewInvalidCharacterError(d.buf[pos:], "after top-level value")
|
||||
return wrapSyntacticError(d, err, pos, 0)
|
||||
|
||||
10
vendor/github.com/go-json-experiment/json/jsontext/doc.go
generated
vendored
10
vendor/github.com/go-json-experiment/json/jsontext/doc.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
// Package jsontext implements syntactic processing of JSON
|
||||
// as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785.
|
||||
// JSON is a simple data interchange format that can represent
|
||||
@@ -18,8 +20,8 @@
|
||||
// - a JSON literal (i.e., null, true, or false)
|
||||
// - a JSON string (e.g., "hello, world!")
|
||||
// - a JSON number (e.g., 123.456)
|
||||
// - a start or end delimiter for a JSON object (i.e., '{' or '}')
|
||||
// - a start or end delimiter for a JSON array (i.e., '[' or ']')
|
||||
// - a begin or end delimiter for a JSON object (i.e., '{' or '}')
|
||||
// - a begin or end delimiter for a JSON array (i.e., '[' or ']')
|
||||
//
|
||||
// A JSON token is represented by the [Token] type in Go. Technically,
|
||||
// there are two additional structural characters (i.e., ':' and ','),
|
||||
@@ -96,6 +98,10 @@
|
||||
// RFC 7493 is a stricter subset of RFC 8259 and fully compliant with it.
|
||||
// In particular, it makes specific choices about behavior that RFC 8259
|
||||
// leaves as undefined in order to ensure greater interoperability.
|
||||
//
|
||||
// # Security Considerations
|
||||
//
|
||||
// See the "Security Considerations" section in [encoding/json/v2].
|
||||
package jsontext
|
||||
|
||||
// requireKeyedLiterals can be embedded in a struct to require keyed literals.
|
||||
|
||||
37
vendor/github.com/go-json-experiment/json/jsontext/encode.go
generated
vendored
37
vendor/github.com/go-json-experiment/json/jsontext/encode.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
@@ -72,8 +74,8 @@ type encodeBuffer struct {
|
||||
|
||||
// maxValue is the approximate maximum Value size passed to WriteValue.
|
||||
maxValue int
|
||||
// unusedCache is the buffer returned by the UnusedBuffer method.
|
||||
unusedCache []byte
|
||||
// availBuffer is the buffer returned by the AvailableBuffer method.
|
||||
availBuffer []byte // always has zero length
|
||||
// bufStats is statistics about buffer utilization.
|
||||
// It is only used with pooled encoders in pools.go.
|
||||
bufStats bufferStatistics
|
||||
@@ -105,14 +107,19 @@ func (e *Encoder) Reset(w io.Writer, opts ...Options) {
|
||||
case e.s.Flags.Get(jsonflags.WithinArshalCall):
|
||||
panic("jsontext: cannot reset Encoder passed to json.MarshalerTo")
|
||||
}
|
||||
e.s.reset(nil, w, opts...)
|
||||
// Reuse the buffer if it does not alias a previous [bytes.Buffer].
|
||||
b := e.s.Buf[:0]
|
||||
if _, ok := e.s.wr.(*bytes.Buffer); ok {
|
||||
b = nil
|
||||
}
|
||||
e.s.reset(b, w, opts...)
|
||||
}
|
||||
|
||||
func (e *encoderState) reset(b []byte, w io.Writer, opts ...Options) {
|
||||
e.state.reset()
|
||||
e.encodeBuffer = encodeBuffer{Buf: b, wr: w, bufStats: e.bufStats}
|
||||
e.encodeBuffer = encodeBuffer{Buf: b, wr: w, availBuffer: e.availBuffer, bufStats: e.bufStats}
|
||||
if bb, ok := w.(*bytes.Buffer); ok && bb != nil {
|
||||
e.Buf = bb.Bytes()[bb.Len():] // alias the unused buffer of bb
|
||||
e.Buf = bb.AvailableBuffer() // alias the unused buffer of bb
|
||||
}
|
||||
opts2 := jsonopts.Struct{} // avoid mutating e.Struct in case it is part of opts
|
||||
opts2.Join(opts...)
|
||||
@@ -463,9 +470,9 @@ func (e *encoderState) AppendRaw(k Kind, safeASCII bool, appendFn func([]byte) (
|
||||
isVerbatim := safeASCII || !jsonwire.NeedEscape(b[pos+len(`"`):len(b)-len(`"`)])
|
||||
if !isVerbatim {
|
||||
var err error
|
||||
b2 := append(e.unusedCache, b[pos+len(`"`):len(b)-len(`"`)]...)
|
||||
b2 := append(e.availBuffer, b[pos+len(`"`):len(b)-len(`"`)]...)
|
||||
b, err = jsonwire.AppendQuote(b[:pos], string(b2), &e.Flags)
|
||||
e.unusedCache = b2[:0]
|
||||
e.availBuffer = b2[:0]
|
||||
if err != nil {
|
||||
return wrapSyntacticError(e, err, pos, +1)
|
||||
}
|
||||
@@ -711,7 +718,7 @@ func (e *encoderState) reformatValue(dst []byte, src Value, depth int) ([]byte,
|
||||
// appends it to the end of src, reformatting whitespace and strings as needed.
|
||||
// It returns the extended dst buffer and the number of consumed input bytes.
|
||||
func (e *encoderState) reformatObject(dst []byte, src Value, depth int) ([]byte, int, error) {
|
||||
// Append object start.
|
||||
// Append object begin.
|
||||
if len(src) == 0 || src[0] != '{' {
|
||||
panic("BUG: reformatObject must be called with a buffer that starts with '{'")
|
||||
} else if depth == maxNestingDepth+1 {
|
||||
@@ -822,7 +829,7 @@ func (e *encoderState) reformatObject(dst []byte, src Value, depth int) ([]byte,
|
||||
// appends it to the end of dst, reformatting whitespace and strings as needed.
|
||||
// It returns the extended dst buffer and the number of consumed input bytes.
|
||||
func (e *encoderState) reformatArray(dst []byte, src Value, depth int) ([]byte, int, error) {
|
||||
// Append array start.
|
||||
// Append array begin.
|
||||
if len(src) == 0 || src[0] != '[' {
|
||||
panic("BUG: reformatArray must be called with a buffer that starts with '['")
|
||||
} else if depth == maxNestingDepth+1 {
|
||||
@@ -898,20 +905,20 @@ func (e *Encoder) OutputOffset() int64 {
|
||||
return e.s.previousOffsetEnd()
|
||||
}
|
||||
|
||||
// UnusedBuffer returns a zero-length buffer with a possible non-zero capacity.
|
||||
// AvailableBuffer returns a zero-length buffer with a possible non-zero capacity.
|
||||
// This buffer is intended to be used to populate a [Value]
|
||||
// being passed to an immediately succeeding [Encoder.WriteValue] call.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// b := d.UnusedBuffer()
|
||||
// b := d.AvailableBuffer()
|
||||
// b = append(b, '"')
|
||||
// b = appendString(b, v) // append the string formatting of v
|
||||
// b = append(b, '"')
|
||||
// ... := d.WriteValue(b)
|
||||
//
|
||||
// It is the user's responsibility to ensure that the value is valid JSON.
|
||||
func (e *Encoder) UnusedBuffer() []byte {
|
||||
func (e *Encoder) AvailableBuffer() []byte {
|
||||
// NOTE: We don't return e.buf[len(e.buf):cap(e.buf)] since WriteValue would
|
||||
// need to take special care to avoid mangling the data while reformatting.
|
||||
// WriteValue can't easily identify whether the input Value aliases e.buf
|
||||
@@ -919,10 +926,10 @@ func (e *Encoder) UnusedBuffer() []byte {
|
||||
// Should this ever alias e.buf, we need to consider how it operates with
|
||||
// the specialized performance optimization for bytes.Buffer.
|
||||
n := 1 << bits.Len(uint(e.s.maxValue|63)) // fast approximation for max length
|
||||
if cap(e.s.unusedCache) < n {
|
||||
e.s.unusedCache = make([]byte, 0, n)
|
||||
if cap(e.s.availBuffer) < n {
|
||||
e.s.availBuffer = make([]byte, 0, n)
|
||||
}
|
||||
return e.s.unusedCache
|
||||
return e.s.availBuffer
|
||||
}
|
||||
|
||||
// StackDepth returns the depth of the state machine for written JSON data.
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/jsontext/errors.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/jsontext/errors.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/jsontext/export.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/jsontext/export.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
|
||||
3
vendor/github.com/go-json-experiment/json/jsontext/options.go
generated
vendored
3
vendor/github.com/go-json-experiment/json/jsontext/options.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
@@ -269,6 +271,7 @@ func WithIndentPrefix(prefix string) Options {
|
||||
|
||||
/*
|
||||
// TODO(https://go.dev/issue/56733): Implement WithByteLimit and WithDepthLimit.
|
||||
// Remember to also update the "Security Considerations" section.
|
||||
|
||||
// WithByteLimit sets a limit on the number of bytes of input or output bytes
|
||||
// that may be consumed or produced for each top-level JSON value.
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/jsontext/pools.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/jsontext/pools.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/jsontext/quote.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/jsontext/quote.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
|
||||
6
vendor/github.com/go-json-experiment/json/jsontext/state.go
generated
vendored
6
vendor/github.com/go-json-experiment/json/jsontext/state.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
@@ -295,7 +297,7 @@ func (m *stateMachine) appendNumber() error {
|
||||
return m.appendLiteral()
|
||||
}
|
||||
|
||||
// pushObject appends a JSON start object token as next in the sequence.
|
||||
// pushObject appends a JSON begin object token as next in the sequence.
|
||||
// If an error is returned, the state is not mutated.
|
||||
func (m *stateMachine) pushObject() error {
|
||||
switch {
|
||||
@@ -330,7 +332,7 @@ func (m *stateMachine) popObject() error {
|
||||
}
|
||||
}
|
||||
|
||||
// pushArray appends a JSON start array token as next in the sequence.
|
||||
// pushArray appends a JSON begin array token as next in the sequence.
|
||||
// If an error is returned, the state is not mutated.
|
||||
func (m *stateMachine) pushArray() error {
|
||||
switch {
|
||||
|
||||
10
vendor/github.com/go-json-experiment/json/jsontext/token.go
generated
vendored
10
vendor/github.com/go-json-experiment/json/jsontext/token.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
@@ -31,8 +33,8 @@ var errInvalidToken = errors.New("invalid jsontext.Token")
|
||||
// - a JSON literal (i.e., null, true, or false)
|
||||
// - a JSON string (e.g., "hello, world!")
|
||||
// - a JSON number (e.g., 123.456)
|
||||
// - a start or end delimiter for a JSON object (i.e., { or } )
|
||||
// - a start or end delimiter for a JSON array (i.e., [ or ] )
|
||||
// - a begin or end delimiter for a JSON object (i.e., { or } )
|
||||
// - a begin or end delimiter for a JSON array (i.e., [ or ] )
|
||||
//
|
||||
// A Token cannot represent entire array or object values, while a [Value] can.
|
||||
// There is no Token to represent commas and colons since
|
||||
@@ -479,9 +481,9 @@ func (t Token) Kind() Kind {
|
||||
// - 't': true
|
||||
// - '"': string
|
||||
// - '0': number
|
||||
// - '{': object start
|
||||
// - '{': object begin
|
||||
// - '}': object end
|
||||
// - '[': array start
|
||||
// - '[': array begin
|
||||
// - ']': array end
|
||||
//
|
||||
// An invalid kind is usually represented using 0,
|
||||
|
||||
2
vendor/github.com/go-json-experiment/json/jsontext/value.go
generated
vendored
2
vendor/github.com/go-json-experiment/json/jsontext/value.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package jsontext
|
||||
|
||||
import (
|
||||
|
||||
273
vendor/github.com/go-json-experiment/json/migrate.sh
generated
vendored
273
vendor/github.com/go-json-experiment/json/migrate.sh
generated
vendored
@@ -3,241 +3,46 @@
|
||||
GOROOT=${1:-../go}
|
||||
JSONROOT="."
|
||||
|
||||
# Check if the Go toolchain has a clean checkout.
|
||||
if [ -n "$(cd $GOROOT; git status --porcelain)" ]; then
|
||||
(cd $GOROOT; git status --porcelain)
|
||||
echo "Working directory is not clean."
|
||||
echo ""
|
||||
echo "To cleanup, run:"
|
||||
echo " (cd $GOROOT && git checkout . && git clean -fd)"
|
||||
exit 1
|
||||
fi
|
||||
cp $JSONROOT/alias_gen.go $JSONROOT/alias_gen.go.bak
|
||||
rm -r $JSONROOT/*.go $JSONROOT/internal $JSONROOT/jsontext $JSONROOT/v1
|
||||
mv $JSONROOT/alias_gen.go.bak $JSONROOT/alias_gen.go
|
||||
cp -r $GOROOT/src/encoding/json/v2/*.go $JSONROOT/
|
||||
cp -r $GOROOT/src/encoding/json/internal/ $JSONROOT/internal/
|
||||
cp -r $GOROOT/src/encoding/json/jsontext/ $JSONROOT/jsontext/
|
||||
mkdir $JSONROOT/v1
|
||||
for X in $GOROOT/src/encoding/json/v2_*.go; do
|
||||
cp $X $JSONROOT/v1/$(basename $X | sed "s/v2_//")
|
||||
done
|
||||
cd $JSONROOT
|
||||
for X in $(git ls-files --cached --others --exclude-standard | grep ".*[.]go$"); do
|
||||
if [ ! -e "$X" ]; then
|
||||
continue
|
||||
fi
|
||||
sed -i 's/go:build goexperiment.jsonv2$/go:build !goexperiment.jsonv2 || !go1.25/' $X
|
||||
sed -i 's|"encoding/json/v2"|"github.com/go-json-experiment/json"|' $X
|
||||
sed -i 's|"encoding/json/internal"|"github.com/go-json-experiment/json/internal"|' $X
|
||||
sed -i 's|"encoding/json/internal/jsonflags"|"github.com/go-json-experiment/json/internal/jsonflags"|' $X
|
||||
sed -i 's|"encoding/json/internal/jsonopts"|"github.com/go-json-experiment/json/internal/jsonopts"|' $X
|
||||
sed -i 's|"encoding/json/internal/jsontest"|"github.com/go-json-experiment/json/internal/jsontest"|' $X
|
||||
sed -i 's|"encoding/json/internal/jsonwire"|"github.com/go-json-experiment/json/internal/jsonwire"|' $X
|
||||
sed -i 's|"encoding/json/jsontext"|"github.com/go-json-experiment/json/jsontext"|' $X
|
||||
sed -i 's|"encoding/json"|"github.com/go-json-experiment/json/v1"|' $X
|
||||
sed -i 's|"internal/zstd"|"github.com/go-json-experiment/json/internal/zstd"|' $X
|
||||
goimports -w $X
|
||||
done
|
||||
sed -i 's/v2[.]struct/json.struct/' $JSONROOT/errors_test.go
|
||||
sed -i 's|jsonv1 "github.com/go-json-experiment/json/v1"|jsonv1 "encoding/json"|' $JSONROOT/bench_test.go
|
||||
|
||||
/bin/rm -rf $GOROOT/src/encoding/json/*
|
||||
cp $JSONROOT/v1/* $GOROOT/src/encoding/json/
|
||||
cp -r $JSONROOT/internal/ $GOROOT/src/encoding/json/internal/
|
||||
mkdir $GOROOT/src/encoding/json/v2/
|
||||
cp -r $JSONROOT/*.go $GOROOT/src/encoding/json/v2/
|
||||
mkdir $GOROOT/src/encoding/json/jsontext/
|
||||
cp -r $JSONROOT/jsontext/*.go $GOROOT/src/encoding/json/jsontext/
|
||||
find $GOROOT/src/encoding/json -type f -exec sed -i 's|github[.]com/go-json-experiment/json/v1|encoding/json|g' {} +
|
||||
find $GOROOT/src/encoding/json -type f -exec sed -i 's|github[.]com/go-json-experiment/json/|encoding/json/|g' {} +
|
||||
find $GOROOT/src/encoding/json -type f -exec sed -i 's|github[.]com/go-json-experiment/json|encoding/json/v2|g' {} +
|
||||
# TODO(go1.25): Remove test that relies on "synctest" that is not available yet.
|
||||
sed -i '/Issue #73733/,+17d' $JSONROOT/v1/encode_test.go
|
||||
goimports -w $JSONROOT/v1/encode_test.go
|
||||
|
||||
# Adjust for changed package path.
|
||||
sed -i 's/json\.struct/v2.struct/g' $GOROOT/src/encoding/json/v2/errors_test.go
|
||||
# Remove documentation that only makes sense within the stdlib.
|
||||
sed -i '/This package .* is experimental/,+4d' $JSONROOT/doc.go
|
||||
sed -i '/This package .* is experimental/,+4d' $JSONROOT/jsontext/doc.go
|
||||
|
||||
# Adjust tests that hardcode formatted error strings.
|
||||
sed -i 's/}`, "Time.UnmarshalJSON: input is not a JSON string/}`, "json: cannot unmarshal JSON object into Go type time.Time/g' $GOROOT/src/time/time_test.go
|
||||
sed -i 's/]`, "Time.UnmarshalJSON: input is not a JSON string/]`, "json: cannot unmarshal JSON array into Go type time.Time/g' $GOROOT/src/time/time_test.go
|
||||
git checkout internal/zstd # we still need local copy of zstd for testing
|
||||
|
||||
# Adjust for changed dependency tree.
|
||||
sed -i 's|encoding/json|encoding/json/v2|g' $GOROOT/src/cmd/go/internal/imports/scan_test.go
|
||||
sed -i 's|encoding/binary|internal/reflectlite|g' $GOROOT/src/cmd/go/internal/imports/scan_test.go
|
||||
LINE=$(sed -n '/encoding\/json, encoding\/pem, encoding\/xml, mime;/=' $GOROOT/src/go/build/deps_test.go)
|
||||
sed -i 's|encoding/json, encoding/pem, encoding/xml, mime|encoding/pem, encoding/xml, mime|g' $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 1)) i\\\\" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 2)) i\\\tSTR, errors" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 3)) i\\\t< encoding/json/internal" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 4)) i\\\t< encoding/json/internal/jsonflags" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 5)) i\\\t< encoding/json/internal/jsonopts" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 6)) i\\\t< encoding/json/internal/jsonwire" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 7)) i\\\t< encoding/json/jsontext;" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 8)) i\\\\" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+ 9)) i\\\tFMT," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+10)) i\\\tencoding/hex," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+11)) i\\\tencoding/base32," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+12)) i\\\tencoding/base64," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+13)) i\\\tencoding/binary," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+14)) i\\\tencoding/json/jsontext," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+15)) i\\\tencoding/json/internal," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+16)) i\\\tencoding/json/internal/jsonflags," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+17)) i\\\tencoding/json/internal/jsonopts," $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+18)) i\\\tencoding/json/internal/jsonwire" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+19)) i\\\t< encoding/json/v2" $GOROOT/src/go/build/deps_test.go
|
||||
sed -i "$((LINE+20)) i\\\t< encoding/json;" $GOROOT/src/go/build/deps_test.go
|
||||
LINE=$(sed -n '/Test-only packages can have anything they want/=' $GOROOT/src/go/build/deps_test.go)
|
||||
sed -i "$((LINE+1)) i\\\tFMT, compress/gzip, embed, encoding/binary < encoding/json/internal/jsontest;" $GOROOT/src/go/build/deps_test.go
|
||||
|
||||
# Adjust for newly added API.
|
||||
ISSUE=71497
|
||||
FILE="next/$ISSUE.txt"
|
||||
NEXT="$GOROOT/doc/next/6-stdlib/99-minor"
|
||||
mkdir -p $NEXT/encoding/json
|
||||
echo "A new [Options] type with associated constructors provide individual options" >> $NEXT/encoding/json/$ISSUE.md
|
||||
echo "to configure \"encoding/json/v2\" to operate with certain historical v1 behavior." >> $NEXT/encoding/json/$ISSUE.md
|
||||
echo "The [DefaultOptionsV2] option represents the set of all options needed" >> $NEXT/encoding/json/$ISSUE.md
|
||||
echo "to configure \"encoding/json/v2\" to entirely operate with historical v1 behavior." >> $NEXT/encoding/json/$ISSUE.md
|
||||
mkdir -p $NEXT/encoding/json/v2
|
||||
echo "A new major version of \"encoding/json\" for processing JSON at a semantic level which is" >> $NEXT/encoding/json/v2/$ISSUE.md
|
||||
echo "functionality that determines the meaning of JSON values as Go values and vice-versa." >> $NEXT/encoding/json/v2/$ISSUE.md
|
||||
mkdir -p $NEXT/encoding/json/jsontext
|
||||
echo "A new package to process JSON at a syntactic level that" >> $NEXT/encoding/json/jsontext/$ISSUE.md
|
||||
echo "is concerned with processing JSON based on its grammar alone." >> $NEXT/encoding/json/jsontext/$ISSUE.md
|
||||
NEXT="$GOROOT/api/next/$ISSUE.txt"
|
||||
echo "pkg encoding/json, func CallMethodsWithLegacySemantics(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func DefaultOptionsV1() jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func EscapeInvalidUTF8(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func FormatBytesWithLegacySemantics(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func FormatTimeWithLegacySemantics(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func MatchCaseSensitiveDelimiter(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func MergeWithLegacySemantics(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func OmitEmptyWithLegacyDefinition(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func ReportErrorsWithLegacySemantics(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func StringifyWithLegacySemantics(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, func UnmarshalArrayFromAnyLength(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, method (*Number) UnmarshalJSONFrom(*jsontext.Decoder, jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, method (*UnmarshalTypeError) Unwrap() error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, method (Number) MarshalJSONTo(*jsontext.Encoder, jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, type Marshaler = json.Marshaler #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, type Options = jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, type RawMessage = jsontext.Value #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, type UnmarshalTypeError struct, Err error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json, type Unmarshaler = json.Unmarshaler #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func AllowDuplicateNames(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func AllowInvalidUTF8(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func AppendFormat([]uint8, []uint8, ...jsonopts.Options) ([]uint8, error) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func AppendQuote[\$0 interface{ ~[]uint8 | ~string }]([]uint8, \$0) ([]uint8, error) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func AppendUnquote[\$0 interface{ ~[]uint8 | ~string }]([]uint8, \$0) ([]uint8, error) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func Bool(bool) Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func CanonicalizeRawFloats(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func CanonicalizeRawInts(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func EscapeForHTML(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func EscapeForJS(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func Float(float64) Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func Int(int64) Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func Multiline(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func NewDecoder(io.Reader, ...jsonopts.Options) *Decoder #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func NewEncoder(io.Writer, ...jsonopts.Options) *Encoder #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func PreserveRawStrings(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func ReorderRawObjects(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func SpaceAfterColon(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func SpaceAfterComma(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func String(string) Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func Uint(uint64) Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func WithIndent(string) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, func WithIndentPrefix(string) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) InputOffset() int64 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) PeekKind() Kind #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) ReadToken() (Token, error) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) ReadValue() (Value, error) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) Reset(io.Reader, ...jsonopts.Options) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) SkipValue() error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) StackDepth() int #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) StackIndex(int) (Kind, int64) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) StackPointer() Pointer #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Decoder) UnreadBuffer() []uint8 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Encoder) OutputOffset() int64 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Encoder) Reset(io.Writer, ...jsonopts.Options) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Encoder) StackDepth() int #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Encoder) StackIndex(int) (Kind, int64) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Encoder) StackPointer() Pointer #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Encoder) UnusedBuffer() []uint8 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Encoder) WriteToken(Token) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Encoder) WriteValue(Value) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*SyntacticError) Error() string #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*SyntacticError) Unwrap() error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Value) Canonicalize(...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Value) Compact(...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Value) Format(...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Value) Indent(...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (*Value) UnmarshalJSON([]uint8) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Kind) String() string #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Pointer) AppendToken(string) Pointer #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Pointer) Contains(Pointer) bool #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Pointer) IsValid() bool #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Pointer) LastToken() string #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Pointer) Parent() Pointer #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Pointer) Tokens() iter.Seq[string] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Token) Bool() bool #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Token) Clone() Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Token) Float() float64 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Token) Int() int64 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Token) Kind() Kind #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Token) String() string #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Token) Uint() uint64 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Value) Clone() Value #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Value) IsValid(...jsonopts.Options) bool #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Value) Kind() Kind #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Value) MarshalJSON() ([]uint8, error) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, method (Value) String() string #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type Decoder struct #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type Encoder struct #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type Kind uint8 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type Options = jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type Pointer string #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type SyntacticError struct #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type SyntacticError struct, ByteOffset int64 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type SyntacticError struct, Err error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type SyntacticError struct, JSONPointer Pointer #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type Token struct #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, type Value []uint8 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var BeginArray Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var BeginObject Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var EndArray Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var EndObject Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var ErrDuplicateName error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var ErrNonStringName error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var False Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var Internal exporter #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var Null Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/jsontext, var True Token #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func DefaultOptionsV2() jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func Deterministic(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func DiscardUnknownMembers(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func FormatNilMapAsNull(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func FormatNilSliceAsNull(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func GetOption[\$0 interface{}](jsonopts.Options, func(\$0) jsonopts.Options) (\$0, bool) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func JoinMarshalers(...*typedArshalers[jsontext.Encoder]) *typedArshalers[jsontext.Encoder] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func JoinOptions(...jsonopts.Options) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func JoinUnmarshalers(...*typedArshalers[jsontext.Decoder]) *typedArshalers[jsontext.Decoder] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func Marshal(interface{}, ...jsonopts.Options) ([]uint8, error) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func MarshalEncode(*jsontext.Encoder, interface{}, ...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func MarshalFunc[\$0 interface{}](func(\$0) ([]uint8, error)) *typedArshalers[jsontext.Encoder] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func MarshalToFunc[\$0 interface{}](func(*jsontext.Encoder, \$0, jsonopts.Options) error) *typedArshalers[jsontext.Encoder] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func MarshalWrite(io.Writer, interface{}, ...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func MatchCaseInsensitiveNames(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func OmitZeroStructFields(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func RejectUnknownMembers(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func StringifyNumbers(bool) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func Unmarshal([]uint8, interface{}, ...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func UnmarshalDecode(*jsontext.Decoder, interface{}, ...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func UnmarshalFromFunc[\$0 interface{}](func(*jsontext.Decoder, \$0, jsonopts.Options) error) *typedArshalers[jsontext.Decoder] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func UnmarshalFunc[\$0 interface{}](func([]uint8, \$0) error) *typedArshalers[jsontext.Decoder] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func UnmarshalRead(io.Reader, interface{}, ...jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func WithMarshalers(*typedArshalers[jsontext.Encoder]) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, func WithUnmarshalers(*typedArshalers[jsontext.Decoder]) jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, method (*SemanticError) Error() string #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, method (*SemanticError) Unwrap() error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type Marshaler interface { MarshalJSON } #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type Marshaler interface, MarshalJSON() ([]uint8, error) #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type MarshalerTo interface { MarshalJSONTo } #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type MarshalerTo interface, MarshalJSONTo(*jsontext.Encoder, jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type Marshalers = typedArshalers[jsontext.Encoder] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type Options = jsonopts.Options #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type SemanticError struct #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type SemanticError struct, ByteOffset int64 #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type SemanticError struct, Err error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type SemanticError struct, GoType reflect.Type #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type SemanticError struct, JSONKind jsontext.Kind #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type SemanticError struct, JSONPointer jsontext.Pointer #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type SemanticError struct, JSONValue jsontext.Value #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type Unmarshaler interface { UnmarshalJSON } #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type Unmarshaler interface, UnmarshalJSON([]uint8) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type UnmarshalerFrom interface { UnmarshalJSONFrom } #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type UnmarshalerFrom interface, UnmarshalJSONFrom(*jsontext.Decoder, jsonopts.Options) error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, type Unmarshalers = typedArshalers[jsontext.Decoder] #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, var ErrUnknownName error #$ISSUE" >> $NEXT
|
||||
echo "pkg encoding/json/v2, var SkipFunc error #$ISSUE" >> $NEXT
|
||||
# The following declarations were moved to encoding/json/v2 or encoding/json/jsontext.
|
||||
EXCEPT="$GOROOT/api/except.txt"
|
||||
echo "pkg encoding/json, method (*RawMessage) UnmarshalJSON([]uint8) error" >> $EXCEPT
|
||||
echo "pkg encoding/json, method (RawMessage) MarshalJSON() ([]uint8, error)" >> $EXCEPT
|
||||
echo "pkg encoding/json, type Marshaler interface { MarshalJSON }" >> $EXCEPT
|
||||
echo "pkg encoding/json, type Marshaler interface, MarshalJSON() ([]uint8, error)" >> $EXCEPT
|
||||
echo "pkg encoding/json, type RawMessage []uint8" >> $EXCEPT
|
||||
echo "pkg encoding/json, type Unmarshaler interface { UnmarshalJSON }" >> $EXCEPT
|
||||
echo "pkg encoding/json, type Unmarshaler interface, UnmarshalJSON([]uint8) error" >> $EXCEPT
|
||||
|
||||
# Run the tests.
|
||||
(cd $GOROOT/src; ./all.bash)
|
||||
go run alias_gen.go "encoding/json" $JSONROOT/v1
|
||||
go run alias_gen.go "encoding/json/v2" $JSONROOT
|
||||
go run alias_gen.go "encoding/json/jsontext" $JSONROOT/jsontext
|
||||
|
||||
7
vendor/github.com/go-json-experiment/json/options.go
generated
vendored
7
vendor/github.com/go-json-experiment/json/options.go
generated
vendored
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.jsonv2 || !go1.25
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
@@ -255,7 +257,7 @@ func (*unmarshalersOption) JSONOptions(internal.NotForPublicUse) {}
|
||||
|
||||
// Inject support into "jsonopts" to handle these types.
|
||||
func init() {
|
||||
jsonopts.GetUnknownOption = func(src *jsonopts.Struct, zero jsonopts.Options) (any, bool) {
|
||||
jsonopts.GetUnknownOption = func(src jsonopts.Struct, zero jsonopts.Options) (any, bool) {
|
||||
switch zero.(type) {
|
||||
case *marshalersOption:
|
||||
if !src.Flags.Has(jsonflags.Marshalers) {
|
||||
@@ -271,7 +273,7 @@ func init() {
|
||||
panic(fmt.Sprintf("unknown option %T", zero))
|
||||
}
|
||||
}
|
||||
jsonopts.JoinUnknownOption = func(dst *jsonopts.Struct, src jsonopts.Options) {
|
||||
jsonopts.JoinUnknownOption = func(dst jsonopts.Struct, src jsonopts.Options) jsonopts.Struct {
|
||||
switch src := src.(type) {
|
||||
case *marshalersOption:
|
||||
dst.Flags.Set(jsonflags.Marshalers | 1)
|
||||
@@ -282,5 +284,6 @@ func init() {
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown option %T", src))
|
||||
}
|
||||
return dst
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user