MCPcopy Create free account
hub / github.com/bet365/jingo / NewStructEncoder

Function NewStructEncoder

structencoder.go:79–156  ·  view source on GitHub ↗

NewStructEncoder compiles a set of instructions for marhsaling a struct shape to a JSON document.

(t interface{})

Source from the content-addressed store, hash-verified

77
78// NewStructEncoder compiles a set of instructions for marhsaling a struct shape to a JSON document.
79func NewStructEncoder(t interface{}) *StructEncoder {
80 e := &StructEncoder{}
81 e.t = t
82 tt := reflect.TypeOf(t)
83
84 e.chunk("{")
85
86 emit := 0 // track number of fields we emit
87 // pass over each field in the struct to build up our instruction set for each
88 for e.i = 0; e.i < tt.NumField(); e.i++ {
89 e.f = tt.Field(e.i)
90
91 tag, opts := parseTag(e.f.Tag.Get("json")) // we're using tags to nominate inclusion
92 if tag == "" {
93 continue
94 }
95 emit++
96
97 // write the key
98 if emit > 1 {
99 e.chunk(",")
100 }
101 e.chunk(`"` + tag + `":`)
102
103 switch {
104 /// support calling .String() when the 'stringer' option is passed
105 case opts.Contains("stringer") && reflect.ValueOf(e.t).Field(e.i).MethodByName("String").Kind() != reflect.Invalid:
106 e.optInstrStringer()
107
108 /// support calling .JSONEncode(*Buffer) when the 'encoder' option is passed
109 case opts.Contains("encoder"):
110
111 // requrie explicit opt-in for JSONMarshaler implementation
112 t := reflect.ValueOf(e.t).Field(e.i).Type()
113 if t.Kind() != reflect.Ptr {
114 t = reflect.PtrTo(t)
115 }
116
117 if _, ok := t.MethodByName("EncodeJSON"); ok {
118 e.optInstrEncoderWriter()
119 break
120 }
121
122 // default to JSONEncoder implementation for any other encoder fields
123 e.optInstrEncoder()
124
125 /// support writing byteslice-like items using 'raw' option.
126 case opts.Contains("raw"):
127 e.optInstrRaw()
128
129 /// suport escaping reserved json characters from byteslice-like items and slices
130 case opts.Contains("escape"):
131 e.optInstrEscape()
132
133 /// time is a type of struct, not a kind, so somewhat of a special case here.
134 case e.f.Type == timeType:
135 e.chunk(`"`)
136 e.val(ptrTimeToBuf)

Callers 15

valueInstMethod · 0.85
structInstrMethod · 0.85
ptrStrctInstrMethod · 0.85
ExampleFunction · 0.85
Example_testStruct2Function · 0.85
Test_NilStructFunction · 0.85
Test_StructWithEscapesFunction · 0.85
Test_StructWithRecursionFunction · 0.85
Test_UnicodeFunction · 0.85
BenchmarkUnicodeFunction · 0.85
Test_UnicodeLargeFunction · 0.85
BenchmarkUnicodeLargeFunction · 0.85

Calls 12

chunkMethod · 0.95
optInstrStringerMethod · 0.95
optInstrEncoderWriterMethod · 0.95
optInstrEncoderMethod · 0.95
optInstrRawMethod · 0.95
optInstrEscapeMethod · 0.95
valMethod · 0.95
ptrstringvalMethod · 0.95
valueInstMethod · 0.95
flunkMethod · 0.95
parseTagFunction · 0.85
ContainsMethod · 0.80

Tested by 14

ExampleFunction · 0.68
Example_testStruct2Function · 0.68
Test_NilStructFunction · 0.68
Test_StructWithEscapesFunction · 0.68
Test_StructWithRecursionFunction · 0.68
Test_UnicodeFunction · 0.68
BenchmarkUnicodeFunction · 0.68
Test_UnicodeLargeFunction · 0.68
BenchmarkUnicodeLargeFunction · 0.68
Test_TimeFunction · 0.68
BenchmarkTimeFunction · 0.68
BenchmarkJsonFunction · 0.68