| | |
| | |
| | |
| |
|
| | |
| |
|
| | package jsonopts |
| |
|
| | import ( |
| | "encoding/json/internal" |
| | "encoding/json/internal/jsonflags" |
| | ) |
| |
|
| | |
| | type Options interface { |
| | |
| | JSONOptions(internal.NotForPublicUse) |
| | } |
| |
|
| | |
| | |
| | type Struct struct { |
| | Flags jsonflags.Flags |
| |
|
| | CoderValues |
| | ArshalValues |
| | } |
| |
|
| | type CoderValues struct { |
| | Indent string |
| | IndentPrefix string |
| | ByteLimit int64 |
| | DepthLimit int |
| | } |
| |
|
| | type ArshalValues struct { |
| | |
| | |
| | |
| |
|
| | Marshalers any |
| | Unmarshalers any |
| |
|
| | Format string |
| | FormatDepth int |
| | } |
| |
|
| | |
| | var DefaultOptionsV2 = Struct{ |
| | Flags: jsonflags.Flags{ |
| | Presence: uint64(jsonflags.DefaultV1Flags), |
| | Values: uint64(0), |
| | }, |
| | } |
| |
|
| | |
| | var DefaultOptionsV1 = Struct{ |
| | Flags: jsonflags.Flags{ |
| | Presence: uint64(jsonflags.DefaultV1Flags), |
| | Values: uint64(jsonflags.DefaultV1Flags), |
| | }, |
| | } |
| |
|
| | func (*Struct) JSONOptions(internal.NotForPublicUse) {} |
| |
|
| | |
| | |
| | var GetUnknownOption = func(Struct, Options) (any, bool) { panic("unknown option") } |
| |
|
| | func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { |
| | |
| | structOpts, ok := opts.(*Struct) |
| | if !ok { |
| | var structOpts2 Struct |
| | structOpts2.Join(opts) |
| | structOpts = &structOpts2 |
| | } |
| |
|
| | |
| | var zero T |
| | switch opt := setter(zero).(type) { |
| | case jsonflags.Bools: |
| | v := structOpts.Flags.Get(opt) |
| | ok := structOpts.Flags.Has(opt) |
| | return any(v).(T), ok |
| | case Indent: |
| | if !structOpts.Flags.Has(jsonflags.Indent) { |
| | return zero, false |
| | } |
| | return any(structOpts.Indent).(T), true |
| | case IndentPrefix: |
| | if !structOpts.Flags.Has(jsonflags.IndentPrefix) { |
| | return zero, false |
| | } |
| | return any(structOpts.IndentPrefix).(T), true |
| | case ByteLimit: |
| | if !structOpts.Flags.Has(jsonflags.ByteLimit) { |
| | return zero, false |
| | } |
| | return any(structOpts.ByteLimit).(T), true |
| | case DepthLimit: |
| | if !structOpts.Flags.Has(jsonflags.DepthLimit) { |
| | return zero, false |
| | } |
| | return any(structOpts.DepthLimit).(T), true |
| | default: |
| | v, ok := GetUnknownOption(*structOpts, opt) |
| | return v.(T), ok |
| | } |
| | } |
| |
|
| | |
| | |
| | var JoinUnknownOption = func(Struct, Options) Struct { panic("unknown option") } |
| |
|
| | func (dst *Struct) Join(srcs ...Options) { |
| | dst.join(false, srcs...) |
| | } |
| |
|
| | func (dst *Struct) JoinWithoutCoderOptions(srcs ...Options) { |
| | dst.join(true, srcs...) |
| | } |
| |
|
| | func (dst *Struct) join(excludeCoderOptions bool, srcs ...Options) { |
| | for _, src := range srcs { |
| | switch src := src.(type) { |
| | case nil: |
| | continue |
| | case jsonflags.Bools: |
| | if excludeCoderOptions { |
| | src &= ^jsonflags.AllCoderFlags |
| | } |
| | dst.Flags.Set(src) |
| | case Indent: |
| | if excludeCoderOptions { |
| | continue |
| | } |
| | dst.Flags.Set(jsonflags.Multiline | jsonflags.Indent | 1) |
| | dst.Indent = string(src) |
| | case IndentPrefix: |
| | if excludeCoderOptions { |
| | continue |
| | } |
| | dst.Flags.Set(jsonflags.Multiline | jsonflags.IndentPrefix | 1) |
| | dst.IndentPrefix = string(src) |
| | case ByteLimit: |
| | if excludeCoderOptions { |
| | continue |
| | } |
| | dst.Flags.Set(jsonflags.ByteLimit | 1) |
| | dst.ByteLimit = int64(src) |
| | case DepthLimit: |
| | if excludeCoderOptions { |
| | continue |
| | } |
| | dst.Flags.Set(jsonflags.DepthLimit | 1) |
| | dst.DepthLimit = int(src) |
| | case *Struct: |
| | srcFlags := src.Flags |
| | if excludeCoderOptions { |
| | srcFlags.Clear(jsonflags.AllCoderFlags) |
| | } |
| | dst.Flags.Join(srcFlags) |
| | if srcFlags.Has(jsonflags.NonBooleanFlags) { |
| | if srcFlags.Has(jsonflags.Indent) { |
| | dst.Indent = src.Indent |
| | } |
| | if srcFlags.Has(jsonflags.IndentPrefix) { |
| | dst.IndentPrefix = src.IndentPrefix |
| | } |
| | if srcFlags.Has(jsonflags.ByteLimit) { |
| | dst.ByteLimit = src.ByteLimit |
| | } |
| | if srcFlags.Has(jsonflags.DepthLimit) { |
| | dst.DepthLimit = src.DepthLimit |
| | } |
| | if srcFlags.Has(jsonflags.Marshalers) { |
| | dst.Marshalers = src.Marshalers |
| | } |
| | if srcFlags.Has(jsonflags.Unmarshalers) { |
| | dst.Unmarshalers = src.Unmarshalers |
| | } |
| | } |
| | default: |
| | *dst = JoinUnknownOption(*dst, src) |
| | } |
| | } |
| | } |
| |
|
| | type ( |
| | Indent string |
| | IndentPrefix string |
| | ByteLimit int64 |
| | DepthLimit int |
| | |
| | |
| | ) |
| |
|
| | func (Indent) JSONOptions(internal.NotForPublicUse) {} |
| | func (IndentPrefix) JSONOptions(internal.NotForPublicUse) {} |
| | func (ByteLimit) JSONOptions(internal.NotForPublicUse) {} |
| | func (DepthLimit) JSONOptions(internal.NotForPublicUse) {} |
| |
|