annotate vendor/gopkg.in/yaml.v3/encode.go @ 81:6ce24b93c8d0 draft

I keep inserting random bugs Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Tue, 12 Dec 2023 14:27:29 +0000
parents d8727551f403
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
74
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
1 //
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
2 // Copyright (c) 2011-2019 Canonical Ltd
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
3 //
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
4 // Licensed under the Apache License, Version 2.0 (the "License");
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
5 // you may not use this file except in compliance with the License.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
6 // You may obtain a copy of the License at
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
7 //
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
8 // http://www.apache.org/licenses/LICENSE-2.0
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
9 //
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
10 // Unless required by applicable law or agreed to in writing, software
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
11 // distributed under the License is distributed on an "AS IS" BASIS,
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
13 // See the License for the specific language governing permissions and
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
14 // limitations under the License.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
15
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
16 package yaml
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
17
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
18 import (
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
19 "encoding"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
20 "fmt"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
21 "io"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
22 "reflect"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
23 "regexp"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
24 "sort"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
25 "strconv"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
26 "strings"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
27 "time"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
28 "unicode/utf8"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
29 )
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
30
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
31 type encoder struct {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
32 emitter yaml_emitter_t
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
33 event yaml_event_t
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
34 out []byte
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
35 flow bool
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
36 indent int
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
37 doneInit bool
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
38 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
39
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
40 func newEncoder() *encoder {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
41 e := &encoder{}
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
42 yaml_emitter_initialize(&e.emitter)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
43 yaml_emitter_set_output_string(&e.emitter, &e.out)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
44 yaml_emitter_set_unicode(&e.emitter, true)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
45 return e
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
46 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
47
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
48 func newEncoderWithWriter(w io.Writer) *encoder {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
49 e := &encoder{}
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
50 yaml_emitter_initialize(&e.emitter)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
51 yaml_emitter_set_output_writer(&e.emitter, w)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
52 yaml_emitter_set_unicode(&e.emitter, true)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
53 return e
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
54 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
55
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
56 func (e *encoder) init() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
57 if e.doneInit {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
58 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
59 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
60 if e.indent == 0 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
61 e.indent = 4
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
62 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
63 e.emitter.best_indent = e.indent
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
64 yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
65 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
66 e.doneInit = true
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
67 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
68
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
69 func (e *encoder) finish() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
70 e.emitter.open_ended = false
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
71 yaml_stream_end_event_initialize(&e.event)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
72 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
73 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
74
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
75 func (e *encoder) destroy() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
76 yaml_emitter_delete(&e.emitter)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
77 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
78
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
79 func (e *encoder) emit() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
80 // This will internally delete the e.event value.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
81 e.must(yaml_emitter_emit(&e.emitter, &e.event))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
82 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
83
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
84 func (e *encoder) must(ok bool) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
85 if !ok {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
86 msg := e.emitter.problem
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
87 if msg == "" {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
88 msg = "unknown problem generating YAML content"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
89 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
90 failf("%s", msg)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
91 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
92 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
93
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
94 func (e *encoder) marshalDoc(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
95 e.init()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
96 var node *Node
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
97 if in.IsValid() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
98 node, _ = in.Interface().(*Node)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
99 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
100 if node != nil && node.Kind == DocumentNode {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
101 e.nodev(in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
102 } else {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
103 yaml_document_start_event_initialize(&e.event, nil, nil, true)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
104 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
105 e.marshal(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
106 yaml_document_end_event_initialize(&e.event, true)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
107 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
108 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
109 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
110
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
111 func (e *encoder) marshal(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
112 tag = shortTag(tag)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
113 if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
114 e.nilv()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
115 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
116 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
117 iface := in.Interface()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
118 switch value := iface.(type) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
119 case *Node:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
120 e.nodev(in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
121 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
122 case Node:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
123 if !in.CanAddr() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
124 var n = reflect.New(in.Type()).Elem()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
125 n.Set(in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
126 in = n
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
127 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
128 e.nodev(in.Addr())
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
129 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
130 case time.Time:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
131 e.timev(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
132 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
133 case *time.Time:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
134 e.timev(tag, in.Elem())
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
135 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
136 case time.Duration:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
137 e.stringv(tag, reflect.ValueOf(value.String()))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
138 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
139 case Marshaler:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
140 v, err := value.MarshalYAML()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
141 if err != nil {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
142 fail(err)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
143 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
144 if v == nil {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
145 e.nilv()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
146 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
147 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
148 e.marshal(tag, reflect.ValueOf(v))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
149 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
150 case encoding.TextMarshaler:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
151 text, err := value.MarshalText()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
152 if err != nil {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
153 fail(err)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
154 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
155 in = reflect.ValueOf(string(text))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
156 case nil:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
157 e.nilv()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
158 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
159 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
160 switch in.Kind() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
161 case reflect.Interface:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
162 e.marshal(tag, in.Elem())
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
163 case reflect.Map:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
164 e.mapv(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
165 case reflect.Ptr:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
166 e.marshal(tag, in.Elem())
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
167 case reflect.Struct:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
168 e.structv(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
169 case reflect.Slice, reflect.Array:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
170 e.slicev(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
171 case reflect.String:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
172 e.stringv(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
173 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
174 e.intv(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
175 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
176 e.uintv(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
177 case reflect.Float32, reflect.Float64:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
178 e.floatv(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
179 case reflect.Bool:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
180 e.boolv(tag, in)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
181 default:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
182 panic("cannot marshal type: " + in.Type().String())
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
183 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
184 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
185
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
186 func (e *encoder) mapv(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
187 e.mappingv(tag, func() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
188 keys := keyList(in.MapKeys())
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
189 sort.Sort(keys)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
190 for _, k := range keys {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
191 e.marshal("", k)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
192 e.marshal("", in.MapIndex(k))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
193 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
194 })
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
195 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
196
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
197 func (e *encoder) fieldByIndex(v reflect.Value, index []int) (field reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
198 for _, num := range index {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
199 for {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
200 if v.Kind() == reflect.Ptr {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
201 if v.IsNil() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
202 return reflect.Value{}
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
203 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
204 v = v.Elem()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
205 continue
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
206 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
207 break
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
208 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
209 v = v.Field(num)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
210 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
211 return v
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
212 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
213
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
214 func (e *encoder) structv(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
215 sinfo, err := getStructInfo(in.Type())
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
216 if err != nil {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
217 panic(err)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
218 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
219 e.mappingv(tag, func() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
220 for _, info := range sinfo.FieldsList {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
221 var value reflect.Value
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
222 if info.Inline == nil {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
223 value = in.Field(info.Num)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
224 } else {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
225 value = e.fieldByIndex(in, info.Inline)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
226 if !value.IsValid() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
227 continue
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
228 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
229 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
230 if info.OmitEmpty && isZero(value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
231 continue
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
232 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
233 e.marshal("", reflect.ValueOf(info.Key))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
234 e.flow = info.Flow
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
235 e.marshal("", value)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
236 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
237 if sinfo.InlineMap >= 0 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
238 m := in.Field(sinfo.InlineMap)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
239 if m.Len() > 0 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
240 e.flow = false
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
241 keys := keyList(m.MapKeys())
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
242 sort.Sort(keys)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
243 for _, k := range keys {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
244 if _, found := sinfo.FieldsMap[k.String()]; found {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
245 panic(fmt.Sprintf("cannot have key %q in inlined map: conflicts with struct field", k.String()))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
246 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
247 e.marshal("", k)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
248 e.flow = false
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
249 e.marshal("", m.MapIndex(k))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
250 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
251 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
252 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
253 })
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
254 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
255
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
256 func (e *encoder) mappingv(tag string, f func()) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
257 implicit := tag == ""
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
258 style := yaml_BLOCK_MAPPING_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
259 if e.flow {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
260 e.flow = false
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
261 style = yaml_FLOW_MAPPING_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
262 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
263 yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
264 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
265 f()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
266 yaml_mapping_end_event_initialize(&e.event)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
267 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
268 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
269
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
270 func (e *encoder) slicev(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
271 implicit := tag == ""
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
272 style := yaml_BLOCK_SEQUENCE_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
273 if e.flow {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
274 e.flow = false
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
275 style = yaml_FLOW_SEQUENCE_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
276 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
277 e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
278 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
279 n := in.Len()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
280 for i := 0; i < n; i++ {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
281 e.marshal("", in.Index(i))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
282 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
283 e.must(yaml_sequence_end_event_initialize(&e.event))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
284 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
285 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
286
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
287 // isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
288 //
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
289 // The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
290 // in YAML 1.2 and by this package, but these should be marshalled quoted for
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
291 // the time being for compatibility with other parsers.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
292 func isBase60Float(s string) (result bool) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
293 // Fast path.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
294 if s == "" {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
295 return false
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
296 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
297 c := s[0]
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
298 if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
299 return false
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
300 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
301 // Do the full match.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
302 return base60float.MatchString(s)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
303 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
304
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
305 // From http://yaml.org/type/float.html, except the regular expression there
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
306 // is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
307 var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
308
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
309 // isOldBool returns whether s is bool notation as defined in YAML 1.1.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
310 //
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
311 // We continue to force strings that YAML 1.1 would interpret as booleans to be
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
312 // rendered as quotes strings so that the marshalled output valid for YAML 1.1
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
313 // parsing.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
314 func isOldBool(s string) (result bool) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
315 switch s {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
316 case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON",
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
317 "n", "N", "no", "No", "NO", "off", "Off", "OFF":
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
318 return true
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
319 default:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
320 return false
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
321 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
322 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
323
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
324 func (e *encoder) stringv(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
325 var style yaml_scalar_style_t
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
326 s := in.String()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
327 canUsePlain := true
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
328 switch {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
329 case !utf8.ValidString(s):
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
330 if tag == binaryTag {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
331 failf("explicitly tagged !!binary data must be base64-encoded")
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
332 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
333 if tag != "" {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
334 failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
335 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
336 // It can't be encoded directly as YAML so use a binary tag
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
337 // and encode it as base64.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
338 tag = binaryTag
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
339 s = encodeBase64(s)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
340 case tag == "":
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
341 // Check to see if it would resolve to a specific
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
342 // tag when encoded unquoted. If it doesn't,
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
343 // there's no need to quote it.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
344 rtag, _ := resolve("", s)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
345 canUsePlain = rtag == strTag && !(isBase60Float(s) || isOldBool(s))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
346 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
347 // Note: it's possible for user code to emit invalid YAML
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
348 // if they explicitly specify a tag and a string containing
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
349 // text that's incompatible with that tag.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
350 switch {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
351 case strings.Contains(s, "\n"):
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
352 if e.flow {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
353 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
354 } else {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
355 style = yaml_LITERAL_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
356 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
357 case canUsePlain:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
358 style = yaml_PLAIN_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
359 default:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
360 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
361 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
362 e.emitScalar(s, "", tag, style, nil, nil, nil, nil)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
363 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
364
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
365 func (e *encoder) boolv(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
366 var s string
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
367 if in.Bool() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
368 s = "true"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
369 } else {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
370 s = "false"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
371 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
372 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
373 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
374
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
375 func (e *encoder) intv(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
376 s := strconv.FormatInt(in.Int(), 10)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
377 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
378 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
379
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
380 func (e *encoder) uintv(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
381 s := strconv.FormatUint(in.Uint(), 10)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
382 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
383 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
384
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
385 func (e *encoder) timev(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
386 t := in.Interface().(time.Time)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
387 s := t.Format(time.RFC3339Nano)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
388 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
389 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
390
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
391 func (e *encoder) floatv(tag string, in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
392 // Issue #352: When formatting, use the precision of the underlying value
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
393 precision := 64
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
394 if in.Kind() == reflect.Float32 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
395 precision = 32
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
396 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
397
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
398 s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
399 switch s {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
400 case "+Inf":
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
401 s = ".inf"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
402 case "-Inf":
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
403 s = "-.inf"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
404 case "NaN":
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
405 s = ".nan"
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
406 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
407 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
408 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
409
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
410 func (e *encoder) nilv() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
411 e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
412 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
413
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
414 func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t, head, line, foot, tail []byte) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
415 // TODO Kill this function. Replace all initialize calls by their underlining Go literals.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
416 implicit := tag == ""
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
417 if !implicit {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
418 tag = longTag(tag)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
419 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
420 e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
421 e.event.head_comment = head
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
422 e.event.line_comment = line
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
423 e.event.foot_comment = foot
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
424 e.event.tail_comment = tail
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
425 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
426 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
427
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
428 func (e *encoder) nodev(in reflect.Value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
429 e.node(in.Interface().(*Node), "")
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
430 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
431
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
432 func (e *encoder) node(node *Node, tail string) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
433 // Zero nodes behave as nil.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
434 if node.Kind == 0 && node.IsZero() {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
435 e.nilv()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
436 return
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
437 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
438
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
439 // If the tag was not explicitly requested, and dropping it won't change the
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
440 // implicit tag of the value, don't include it in the presentation.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
441 var tag = node.Tag
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
442 var stag = shortTag(tag)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
443 var forceQuoting bool
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
444 if tag != "" && node.Style&TaggedStyle == 0 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
445 if node.Kind == ScalarNode {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
446 if stag == strTag && node.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
447 tag = ""
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
448 } else {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
449 rtag, _ := resolve("", node.Value)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
450 if rtag == stag {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
451 tag = ""
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
452 } else if stag == strTag {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
453 tag = ""
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
454 forceQuoting = true
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
455 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
456 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
457 } else {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
458 var rtag string
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
459 switch node.Kind {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
460 case MappingNode:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
461 rtag = mapTag
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
462 case SequenceNode:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
463 rtag = seqTag
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
464 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
465 if rtag == stag {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
466 tag = ""
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
467 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
468 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
469 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
470
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
471 switch node.Kind {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
472 case DocumentNode:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
473 yaml_document_start_event_initialize(&e.event, nil, nil, true)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
474 e.event.head_comment = []byte(node.HeadComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
475 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
476 for _, node := range node.Content {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
477 e.node(node, "")
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
478 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
479 yaml_document_end_event_initialize(&e.event, true)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
480 e.event.foot_comment = []byte(node.FootComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
481 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
482
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
483 case SequenceNode:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
484 style := yaml_BLOCK_SEQUENCE_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
485 if node.Style&FlowStyle != 0 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
486 style = yaml_FLOW_SEQUENCE_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
487 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
488 e.must(yaml_sequence_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == "", style))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
489 e.event.head_comment = []byte(node.HeadComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
490 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
491 for _, node := range node.Content {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
492 e.node(node, "")
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
493 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
494 e.must(yaml_sequence_end_event_initialize(&e.event))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
495 e.event.line_comment = []byte(node.LineComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
496 e.event.foot_comment = []byte(node.FootComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
497 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
498
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
499 case MappingNode:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
500 style := yaml_BLOCK_MAPPING_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
501 if node.Style&FlowStyle != 0 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
502 style = yaml_FLOW_MAPPING_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
503 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
504 yaml_mapping_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == "", style)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
505 e.event.tail_comment = []byte(tail)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
506 e.event.head_comment = []byte(node.HeadComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
507 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
508
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
509 // The tail logic below moves the foot comment of prior keys to the following key,
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
510 // since the value for each key may be a nested structure and the foot needs to be
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
511 // processed only the entirety of the value is streamed. The last tail is processed
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
512 // with the mapping end event.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
513 var tail string
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
514 for i := 0; i+1 < len(node.Content); i += 2 {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
515 k := node.Content[i]
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
516 foot := k.FootComment
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
517 if foot != "" {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
518 kopy := *k
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
519 kopy.FootComment = ""
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
520 k = &kopy
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
521 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
522 e.node(k, tail)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
523 tail = foot
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
524
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
525 v := node.Content[i+1]
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
526 e.node(v, "")
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
527 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
528
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
529 yaml_mapping_end_event_initialize(&e.event)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
530 e.event.tail_comment = []byte(tail)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
531 e.event.line_comment = []byte(node.LineComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
532 e.event.foot_comment = []byte(node.FootComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
533 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
534
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
535 case AliasNode:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
536 yaml_alias_event_initialize(&e.event, []byte(node.Value))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
537 e.event.head_comment = []byte(node.HeadComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
538 e.event.line_comment = []byte(node.LineComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
539 e.event.foot_comment = []byte(node.FootComment)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
540 e.emit()
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
541
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
542 case ScalarNode:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
543 value := node.Value
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
544 if !utf8.ValidString(value) {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
545 if stag == binaryTag {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
546 failf("explicitly tagged !!binary data must be base64-encoded")
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
547 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
548 if stag != "" {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
549 failf("cannot marshal invalid UTF-8 data as %s", stag)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
550 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
551 // It can't be encoded directly as YAML so use a binary tag
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
552 // and encode it as base64.
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
553 tag = binaryTag
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
554 value = encodeBase64(value)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
555 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
556
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
557 style := yaml_PLAIN_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
558 switch {
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
559 case node.Style&DoubleQuotedStyle != 0:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
560 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
561 case node.Style&SingleQuotedStyle != 0:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
562 style = yaml_SINGLE_QUOTED_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
563 case node.Style&LiteralStyle != 0:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
564 style = yaml_LITERAL_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
565 case node.Style&FoldedStyle != 0:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
566 style = yaml_FOLDED_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
567 case strings.Contains(value, "\n"):
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
568 style = yaml_LITERAL_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
569 case forceQuoting:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
570 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
571 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
572
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
573 e.emitScalar(value, node.Anchor, tag, style, []byte(node.HeadComment), []byte(node.LineComment), []byte(node.FootComment), []byte(tail))
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
574 default:
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
575 failf("cannot encode node with unknown kind %d", node.Kind)
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
576 }
d8727551f403 The Empress (III)
yakumo.izuru
parents:
diff changeset
577 }