diff options
Diffstat (limited to 'vendor/github.com/zclconf/go-cty-yaml/encode.go')
-rw-r--r-- | vendor/github.com/zclconf/go-cty-yaml/encode.go | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty-yaml/encode.go b/vendor/github.com/zclconf/go-cty-yaml/encode.go new file mode 100644 index 0000000..daa1478 --- /dev/null +++ b/vendor/github.com/zclconf/go-cty-yaml/encode.go | |||
@@ -0,0 +1,189 @@ | |||
1 | package yaml | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "fmt" | ||
6 | "strings" | ||
7 | |||
8 | "github.com/zclconf/go-cty/cty" | ||
9 | ) | ||
10 | |||
11 | func (c *Converter) marshal(v cty.Value) ([]byte, error) { | ||
12 | var buf bytes.Buffer | ||
13 | |||
14 | e := &yaml_emitter_t{} | ||
15 | yaml_emitter_initialize(e) | ||
16 | yaml_emitter_set_output_writer(e, &buf) | ||
17 | yaml_emitter_set_unicode(e, true) | ||
18 | |||
19 | var evt yaml_event_t | ||
20 | yaml_stream_start_event_initialize(&evt, yaml_UTF8_ENCODING) | ||
21 | if !yaml_emitter_emit(e, &evt) { | ||
22 | return nil, emitterError(e) | ||
23 | } | ||
24 | yaml_document_start_event_initialize(&evt, nil, nil, true) | ||
25 | if !yaml_emitter_emit(e, &evt) { | ||
26 | return nil, emitterError(e) | ||
27 | } | ||
28 | |||
29 | if err := c.marshalEmit(v, e); err != nil { | ||
30 | return nil, err | ||
31 | } | ||
32 | |||
33 | yaml_document_end_event_initialize(&evt, true) | ||
34 | if !yaml_emitter_emit(e, &evt) { | ||
35 | return nil, emitterError(e) | ||
36 | } | ||
37 | yaml_stream_end_event_initialize(&evt) | ||
38 | if !yaml_emitter_emit(e, &evt) { | ||
39 | return nil, emitterError(e) | ||
40 | } | ||
41 | |||
42 | return buf.Bytes(), nil | ||
43 | } | ||
44 | |||
45 | func (c *Converter) marshalEmit(v cty.Value, e *yaml_emitter_t) error { | ||
46 | ty := v.Type() | ||
47 | switch { | ||
48 | case v.IsNull(): | ||
49 | return c.marshalPrimitive(v, e) | ||
50 | case !v.IsKnown(): | ||
51 | return fmt.Errorf("cannot serialize unknown value as YAML") | ||
52 | case ty.IsPrimitiveType(): | ||
53 | return c.marshalPrimitive(v, e) | ||
54 | case ty.IsTupleType(), ty.IsListType(), ty.IsSetType(): | ||
55 | return c.marshalSequence(v, e) | ||
56 | case ty.IsObjectType(), ty.IsMapType(): | ||
57 | return c.marshalMapping(v, e) | ||
58 | default: | ||
59 | return fmt.Errorf("can't marshal %s as YAML", ty.FriendlyName()) | ||
60 | } | ||
61 | } | ||
62 | |||
63 | func (c *Converter) marshalPrimitive(v cty.Value, e *yaml_emitter_t) error { | ||
64 | var evt yaml_event_t | ||
65 | |||
66 | if v.IsNull() { | ||
67 | yaml_scalar_event_initialize( | ||
68 | &evt, | ||
69 | nil, | ||
70 | nil, | ||
71 | []byte("null"), | ||
72 | true, | ||
73 | true, | ||
74 | yaml_PLAIN_SCALAR_STYLE, | ||
75 | ) | ||
76 | if !yaml_emitter_emit(e, &evt) { | ||
77 | return emitterError(e) | ||
78 | } | ||
79 | return nil | ||
80 | } | ||
81 | |||
82 | switch v.Type() { | ||
83 | case cty.String: | ||
84 | str := v.AsString() | ||
85 | style := yaml_DOUBLE_QUOTED_SCALAR_STYLE | ||
86 | if strings.Contains(str, "\n") { | ||
87 | style = yaml_LITERAL_SCALAR_STYLE | ||
88 | } | ||
89 | yaml_scalar_event_initialize( | ||
90 | &evt, | ||
91 | nil, | ||
92 | nil, | ||
93 | []byte(str), | ||
94 | true, | ||
95 | true, | ||
96 | style, | ||
97 | ) | ||
98 | case cty.Number: | ||
99 | str := v.AsBigFloat().Text('f', -1) | ||
100 | yaml_scalar_event_initialize( | ||
101 | &evt, | ||
102 | nil, | ||
103 | nil, | ||
104 | []byte(str), | ||
105 | true, | ||
106 | true, | ||
107 | yaml_PLAIN_SCALAR_STYLE, | ||
108 | ) | ||
109 | case cty.Bool: | ||
110 | var str string | ||
111 | switch v { | ||
112 | case cty.True: | ||
113 | str = "true" | ||
114 | case cty.False: | ||
115 | str = "false" | ||
116 | } | ||
117 | yaml_scalar_event_initialize( | ||
118 | &evt, | ||
119 | nil, | ||
120 | nil, | ||
121 | []byte(str), | ||
122 | true, | ||
123 | true, | ||
124 | yaml_PLAIN_SCALAR_STYLE, | ||
125 | ) | ||
126 | } | ||
127 | if !yaml_emitter_emit(e, &evt) { | ||
128 | return emitterError(e) | ||
129 | } | ||
130 | return nil | ||
131 | } | ||
132 | |||
133 | func (c *Converter) marshalSequence(v cty.Value, e *yaml_emitter_t) error { | ||
134 | style := yaml_BLOCK_SEQUENCE_STYLE | ||
135 | if c.encodeAsFlow { | ||
136 | style = yaml_FLOW_SEQUENCE_STYLE | ||
137 | } | ||
138 | |||
139 | var evt yaml_event_t | ||
140 | yaml_sequence_start_event_initialize(&evt, nil, nil, true, style) | ||
141 | if !yaml_emitter_emit(e, &evt) { | ||
142 | return emitterError(e) | ||
143 | } | ||
144 | |||
145 | for it := v.ElementIterator(); it.Next(); { | ||
146 | _, v := it.Element() | ||
147 | err := c.marshalEmit(v, e) | ||
148 | if err != nil { | ||
149 | return err | ||
150 | } | ||
151 | } | ||
152 | |||
153 | yaml_sequence_end_event_initialize(&evt) | ||
154 | if !yaml_emitter_emit(e, &evt) { | ||
155 | return emitterError(e) | ||
156 | } | ||
157 | return nil | ||
158 | } | ||
159 | |||
160 | func (c *Converter) marshalMapping(v cty.Value, e *yaml_emitter_t) error { | ||
161 | style := yaml_BLOCK_MAPPING_STYLE | ||
162 | if c.encodeAsFlow { | ||
163 | style = yaml_FLOW_MAPPING_STYLE | ||
164 | } | ||
165 | |||
166 | var evt yaml_event_t | ||
167 | yaml_mapping_start_event_initialize(&evt, nil, nil, true, style) | ||
168 | if !yaml_emitter_emit(e, &evt) { | ||
169 | return emitterError(e) | ||
170 | } | ||
171 | |||
172 | for it := v.ElementIterator(); it.Next(); { | ||
173 | k, v := it.Element() | ||
174 | err := c.marshalEmit(k, e) | ||
175 | if err != nil { | ||
176 | return err | ||
177 | } | ||
178 | err = c.marshalEmit(v, e) | ||
179 | if err != nil { | ||
180 | return err | ||
181 | } | ||
182 | } | ||
183 | |||
184 | yaml_mapping_end_event_initialize(&evt) | ||
185 | if !yaml_emitter_emit(e, &evt) { | ||
186 | return emitterError(e) | ||
187 | } | ||
188 | return nil | ||
189 | } | ||