annotate vendor/gopkg.in/yaml.v2/encode.go @ 71:7819959ac6ca draft

feat: move the blackfriday extension settings out of the render function, improve documentation Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Tue, 03 Oct 2023 02:39:08 +0000
parents 787b5ee0289d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1 package yaml
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
3 import (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
4 "encoding"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
5 "fmt"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6 "io"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7 "reflect"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 "regexp"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9 "sort"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10 "strconv"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 "strings"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12 "time"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13 "unicode/utf8"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16 // jsonNumber is the interface of the encoding/json.Number datatype.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17 // Repeating the interface here avoids a dependency on encoding/json, and also
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 // supports other libraries like jsoniter, which use a similar datatype with
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19 // the same interface. Detecting this interface is useful when dealing with
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20 // structures containing json.Number, which is a string under the hood. The
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21 // encoder should prefer the use of Int64(), Float64() and string(), in that
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22 // order, when encoding this type.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23 type jsonNumber interface {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24 Float64() (float64, error)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25 Int64() (int64, error)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 String() string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29 type encoder struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 emitter yaml_emitter_t
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31 event yaml_event_t
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 out []byte
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33 flow bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 // doneInit holds whether the initial stream_start_event has been
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 // emitted.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 doneInit bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 func newEncoder() *encoder {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40 e := &encoder{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41 yaml_emitter_initialize(&e.emitter)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42 yaml_emitter_set_output_string(&e.emitter, &e.out)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43 yaml_emitter_set_unicode(&e.emitter, true)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 return e
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47 func newEncoderWithWriter(w io.Writer) *encoder {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48 e := &encoder{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49 yaml_emitter_initialize(&e.emitter)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50 yaml_emitter_set_output_writer(&e.emitter, w)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51 yaml_emitter_set_unicode(&e.emitter, true)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52 return e
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 func (e *encoder) init() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56 if e.doneInit {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 e.doneInit = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64 func (e *encoder) finish() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65 e.emitter.open_ended = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 yaml_stream_end_event_initialize(&e.event)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70 func (e *encoder) destroy() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71 yaml_emitter_delete(&e.emitter)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74 func (e *encoder) emit() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 // This will internally delete the e.event value.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76 e.must(yaml_emitter_emit(&e.emitter, &e.event))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79 func (e *encoder) must(ok bool) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80 if !ok {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81 msg := e.emitter.problem
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82 if msg == "" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 msg = "unknown problem generating YAML content"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85 failf("%s", msg)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89 func (e *encoder) marshalDoc(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
90 e.init()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
91 yaml_document_start_event_initialize(&e.event, nil, nil, true)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
92 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93 e.marshal(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94 yaml_document_end_event_initialize(&e.event, true)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98 func (e *encoder) marshal(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 e.nilv()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103 iface := in.Interface()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 switch m := iface.(type) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105 case jsonNumber:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 integer, err := m.Int64()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 if err == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108 // In this case the json.Number is a valid int64
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109 in = reflect.ValueOf(integer)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112 float, err := m.Float64()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113 if err == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114 // In this case the json.Number is a valid float64
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 in = reflect.ValueOf(float)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118 // fallback case - no number could be obtained
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 in = reflect.ValueOf(m.String())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120 case time.Time, *time.Time:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121 // Although time.Time implements TextMarshaler,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 // we don't want to treat it as a string for YAML
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123 // purposes because YAML has special support for
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 // timestamps.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 case Marshaler:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 v, err := m.MarshalYAML()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 fail(err)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 if v == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 e.nilv()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134 in = reflect.ValueOf(v)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 case encoding.TextMarshaler:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 text, err := m.MarshalText()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138 fail(err)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
139 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
140 in = reflect.ValueOf(string(text))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
141 case nil:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
142 e.nilv()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 switch in.Kind() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146 case reflect.Interface:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147 e.marshal(tag, in.Elem())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
148 case reflect.Map:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
149 e.mapv(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
150 case reflect.Ptr:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
151 if in.Type() == ptrTimeType {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
152 e.timev(tag, in.Elem())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
153 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
154 e.marshal(tag, in.Elem())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
155 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
156 case reflect.Struct:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
157 if in.Type() == timeType {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
158 e.timev(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
159 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
160 e.structv(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
161 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
162 case reflect.Slice, reflect.Array:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
163 if in.Type().Elem() == mapItemType {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
164 e.itemsv(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
165 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
166 e.slicev(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
167 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
168 case reflect.String:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
169 e.stringv(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
170 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
171 if in.Type() == durationType {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
172 e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String()))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
173 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
174 e.intv(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
175 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
176 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
177 e.uintv(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
178 case reflect.Float32, reflect.Float64:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
179 e.floatv(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
180 case reflect.Bool:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
181 e.boolv(tag, in)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
182 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
183 panic("cannot marshal type: " + in.Type().String())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
184 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
185 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
186
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
187 func (e *encoder) mapv(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
188 e.mappingv(tag, func() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
189 keys := keyList(in.MapKeys())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
190 sort.Sort(keys)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
191 for _, k := range keys {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
192 e.marshal("", k)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
193 e.marshal("", in.MapIndex(k))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
194 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
195 })
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
196 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
197
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
198 func (e *encoder) itemsv(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
199 e.mappingv(tag, func() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
200 slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
201 for _, item := range slice {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
202 e.marshal("", reflect.ValueOf(item.Key))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
203 e.marshal("", reflect.ValueOf(item.Value))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
204 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
205 })
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
206 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
207
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
208 func (e *encoder) structv(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
209 sinfo, err := getStructInfo(in.Type())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
210 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
211 panic(err)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
212 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
213 e.mappingv(tag, func() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
214 for _, info := range sinfo.FieldsList {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
215 var value reflect.Value
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
216 if info.Inline == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
217 value = in.Field(info.Num)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
218 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
219 value = in.FieldByIndex(info.Inline)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
220 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
221 if info.OmitEmpty && isZero(value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
222 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
223 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
224 e.marshal("", reflect.ValueOf(info.Key))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
225 e.flow = info.Flow
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
226 e.marshal("", value)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
227 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
228 if sinfo.InlineMap >= 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
229 m := in.Field(sinfo.InlineMap)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
230 if m.Len() > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
231 e.flow = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
232 keys := keyList(m.MapKeys())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
233 sort.Sort(keys)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
234 for _, k := range keys {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
235 if _, found := sinfo.FieldsMap[k.String()]; found {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
236 panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String()))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
237 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
238 e.marshal("", k)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
239 e.flow = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
240 e.marshal("", m.MapIndex(k))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
241 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
242 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
243 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
244 })
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
245 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
246
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
247 func (e *encoder) mappingv(tag string, f func()) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
248 implicit := tag == ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
249 style := yaml_BLOCK_MAPPING_STYLE
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
250 if e.flow {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
251 e.flow = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
252 style = yaml_FLOW_MAPPING_STYLE
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
253 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
254 yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
255 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
256 f()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
257 yaml_mapping_end_event_initialize(&e.event)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
258 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
259 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
260
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
261 func (e *encoder) slicev(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
262 implicit := tag == ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
263 style := yaml_BLOCK_SEQUENCE_STYLE
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
264 if e.flow {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
265 e.flow = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
266 style = yaml_FLOW_SEQUENCE_STYLE
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
267 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
268 e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
269 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
270 n := in.Len()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
271 for i := 0; i < n; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
272 e.marshal("", in.Index(i))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
273 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
274 e.must(yaml_sequence_end_event_initialize(&e.event))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
275 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
276 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
277
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
278 // isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
279 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
280 // The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
281 // in YAML 1.2 and by this package, but these should be marshalled quoted for
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
282 // the time being for compatibility with other parsers.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
283 func isBase60Float(s string) (result bool) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
284 // Fast path.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
285 if s == "" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
286 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
287 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
288 c := s[0]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
289 if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
290 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
291 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
292 // Do the full match.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
293 return base60float.MatchString(s)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
294 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
295
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
296 // From http://yaml.org/type/float.html, except the regular expression there
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
297 // is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
298 var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
299
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
300 func (e *encoder) stringv(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
301 var style yaml_scalar_style_t
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
302 s := in.String()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
303 canUsePlain := true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
304 switch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
305 case !utf8.ValidString(s):
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
306 if tag == yaml_BINARY_TAG {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
307 failf("explicitly tagged !!binary data must be base64-encoded")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
308 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
309 if tag != "" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
310 failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
311 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
312 // It can't be encoded directly as YAML so use a binary tag
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
313 // and encode it as base64.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
314 tag = yaml_BINARY_TAG
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
315 s = encodeBase64(s)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
316 case tag == "":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
317 // Check to see if it would resolve to a specific
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
318 // tag when encoded unquoted. If it doesn't,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
319 // there's no need to quote it.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
320 rtag, _ := resolve("", s)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
321 canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
322 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
323 // Note: it's possible for user code to emit invalid YAML
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
324 // if they explicitly specify a tag and a string containing
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
325 // text that's incompatible with that tag.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
326 switch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
327 case strings.Contains(s, "\n"):
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
328 style = yaml_LITERAL_SCALAR_STYLE
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
329 case canUsePlain:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
330 style = yaml_PLAIN_SCALAR_STYLE
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
331 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
332 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
333 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
334 e.emitScalar(s, "", tag, style)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
335 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
336
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
337 func (e *encoder) boolv(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
338 var s string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
339 if in.Bool() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
340 s = "true"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
341 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
342 s = "false"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
343 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
344 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
345 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
346
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
347 func (e *encoder) intv(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
348 s := strconv.FormatInt(in.Int(), 10)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
349 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
350 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
351
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
352 func (e *encoder) uintv(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
353 s := strconv.FormatUint(in.Uint(), 10)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
354 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
355 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
356
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
357 func (e *encoder) timev(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
358 t := in.Interface().(time.Time)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
359 s := t.Format(time.RFC3339Nano)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
360 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
361 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
362
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
363 func (e *encoder) floatv(tag string, in reflect.Value) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
364 // Issue #352: When formatting, use the precision of the underlying value
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
365 precision := 64
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
366 if in.Kind() == reflect.Float32 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
367 precision = 32
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
368 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
369
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
370 s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
371 switch s {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
372 case "+Inf":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
373 s = ".inf"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
374 case "-Inf":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
375 s = "-.inf"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
376 case "NaN":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
377 s = ".nan"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
378 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
379 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
380 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
381
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
382 func (e *encoder) nilv() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
383 e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
384 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
385
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
386 func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
387 implicit := tag == ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
388 e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
389 e.emit()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
390 }