diff options
author | appilon <apilon@hashicorp.com> | 2019-02-27 16:43:31 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-27 16:43:31 -0500 |
commit | 844b5a68d8af4791755b8f0ad293cc99f5959183 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/zclconf/go-cty/cty/json/marshal.go | |
parent | 303b299eeb6b06e939e35905e4b34cb410dd9dc3 (diff) | |
parent | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (diff) | |
download | terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.gz terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.zst terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.zip |
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[MODULES] Switch to Go Modules
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/json/marshal.go')
-rw-r--r-- | vendor/github.com/zclconf/go-cty/cty/json/marshal.go | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/json/marshal.go b/vendor/github.com/zclconf/go-cty/cty/json/marshal.go new file mode 100644 index 0000000..f7bea1a --- /dev/null +++ b/vendor/github.com/zclconf/go-cty/cty/json/marshal.go | |||
@@ -0,0 +1,189 @@ | |||
1 | package json | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "encoding/json" | ||
6 | "sort" | ||
7 | |||
8 | "github.com/zclconf/go-cty/cty" | ||
9 | ) | ||
10 | |||
11 | func marshal(val cty.Value, t cty.Type, path cty.Path, b *bytes.Buffer) error { | ||
12 | // If we're going to decode as DynamicPseudoType then we need to save | ||
13 | // dynamic type information to recover the real type. | ||
14 | if t == cty.DynamicPseudoType && val.Type() != cty.DynamicPseudoType { | ||
15 | return marshalDynamic(val, path, b) | ||
16 | } | ||
17 | |||
18 | if val.IsNull() { | ||
19 | b.WriteString("null") | ||
20 | return nil | ||
21 | } | ||
22 | |||
23 | if !val.IsKnown() { | ||
24 | return path.NewErrorf("value is not known") | ||
25 | } | ||
26 | |||
27 | // The caller should've guaranteed that the given val is conformant with | ||
28 | // the given type t, so we'll proceed under that assumption here. | ||
29 | |||
30 | switch { | ||
31 | case t.IsPrimitiveType(): | ||
32 | switch t { | ||
33 | case cty.String: | ||
34 | json, err := json.Marshal(val.AsString()) | ||
35 | if err != nil { | ||
36 | return path.NewErrorf("failed to serialize value: %s", err) | ||
37 | } | ||
38 | b.Write(json) | ||
39 | return nil | ||
40 | case cty.Number: | ||
41 | if val.RawEquals(cty.PositiveInfinity) || val.RawEquals(cty.NegativeInfinity) { | ||
42 | return path.NewErrorf("cannot serialize infinity as JSON") | ||
43 | } | ||
44 | b.WriteString(val.AsBigFloat().Text('f', -1)) | ||
45 | return nil | ||
46 | case cty.Bool: | ||
47 | if val.True() { | ||
48 | b.WriteString("true") | ||
49 | } else { | ||
50 | b.WriteString("false") | ||
51 | } | ||
52 | return nil | ||
53 | default: | ||
54 | panic("unsupported primitive type") | ||
55 | } | ||
56 | case t.IsListType(), t.IsSetType(): | ||
57 | b.WriteRune('[') | ||
58 | first := true | ||
59 | ety := t.ElementType() | ||
60 | it := val.ElementIterator() | ||
61 | path := append(path, nil) // local override of 'path' with extra element | ||
62 | for it.Next() { | ||
63 | if !first { | ||
64 | b.WriteRune(',') | ||
65 | } | ||
66 | ek, ev := it.Element() | ||
67 | path[len(path)-1] = cty.IndexStep{ | ||
68 | Key: ek, | ||
69 | } | ||
70 | err := marshal(ev, ety, path, b) | ||
71 | if err != nil { | ||
72 | return err | ||
73 | } | ||
74 | first = false | ||
75 | } | ||
76 | b.WriteRune(']') | ||
77 | return nil | ||
78 | case t.IsMapType(): | ||
79 | b.WriteRune('{') | ||
80 | first := true | ||
81 | ety := t.ElementType() | ||
82 | it := val.ElementIterator() | ||
83 | path := append(path, nil) // local override of 'path' with extra element | ||
84 | for it.Next() { | ||
85 | if !first { | ||
86 | b.WriteRune(',') | ||
87 | } | ||
88 | ek, ev := it.Element() | ||
89 | path[len(path)-1] = cty.IndexStep{ | ||
90 | Key: ek, | ||
91 | } | ||
92 | var err error | ||
93 | err = marshal(ek, ek.Type(), path, b) | ||
94 | if err != nil { | ||
95 | return err | ||
96 | } | ||
97 | b.WriteRune(':') | ||
98 | err = marshal(ev, ety, path, b) | ||
99 | if err != nil { | ||
100 | return err | ||
101 | } | ||
102 | first = false | ||
103 | } | ||
104 | b.WriteRune('}') | ||
105 | return nil | ||
106 | case t.IsTupleType(): | ||
107 | b.WriteRune('[') | ||
108 | etys := t.TupleElementTypes() | ||
109 | it := val.ElementIterator() | ||
110 | path := append(path, nil) // local override of 'path' with extra element | ||
111 | i := 0 | ||
112 | for it.Next() { | ||
113 | if i > 0 { | ||
114 | b.WriteRune(',') | ||
115 | } | ||
116 | ety := etys[i] | ||
117 | ek, ev := it.Element() | ||
118 | path[len(path)-1] = cty.IndexStep{ | ||
119 | Key: ek, | ||
120 | } | ||
121 | err := marshal(ev, ety, path, b) | ||
122 | if err != nil { | ||
123 | return err | ||
124 | } | ||
125 | i++ | ||
126 | } | ||
127 | b.WriteRune(']') | ||
128 | return nil | ||
129 | case t.IsObjectType(): | ||
130 | b.WriteRune('{') | ||
131 | atys := t.AttributeTypes() | ||
132 | path := append(path, nil) // local override of 'path' with extra element | ||
133 | |||
134 | names := make([]string, 0, len(atys)) | ||
135 | for k := range atys { | ||
136 | names = append(names, k) | ||
137 | } | ||
138 | sort.Strings(names) | ||
139 | |||
140 | for i, k := range names { | ||
141 | aty := atys[k] | ||
142 | if i > 0 { | ||
143 | b.WriteRune(',') | ||
144 | } | ||
145 | av := val.GetAttr(k) | ||
146 | path[len(path)-1] = cty.GetAttrStep{ | ||
147 | Name: k, | ||
148 | } | ||
149 | var err error | ||
150 | err = marshal(cty.StringVal(k), cty.String, path, b) | ||
151 | if err != nil { | ||
152 | return err | ||
153 | } | ||
154 | b.WriteRune(':') | ||
155 | err = marshal(av, aty, path, b) | ||
156 | if err != nil { | ||
157 | return err | ||
158 | } | ||
159 | } | ||
160 | b.WriteRune('}') | ||
161 | return nil | ||
162 | case t.IsCapsuleType(): | ||
163 | rawVal := val.EncapsulatedValue() | ||
164 | jsonVal, err := json.Marshal(rawVal) | ||
165 | if err != nil { | ||
166 | return path.NewError(err) | ||
167 | } | ||
168 | b.Write(jsonVal) | ||
169 | return nil | ||
170 | default: | ||
171 | // should never happen | ||
172 | return path.NewErrorf("cannot JSON-serialize %s", t.FriendlyName()) | ||
173 | } | ||
174 | } | ||
175 | |||
176 | // marshalDynamic adds an extra wrapping object containing dynamic type | ||
177 | // information for the given value. | ||
178 | func marshalDynamic(val cty.Value, path cty.Path, b *bytes.Buffer) error { | ||
179 | typeJSON, err := MarshalType(val.Type()) | ||
180 | if err != nil { | ||
181 | return path.NewErrorf("failed to serialize type: %s", err) | ||
182 | } | ||
183 | b.WriteString(`{"value":`) | ||
184 | marshal(val, val.Type(), path, b) | ||
185 | b.WriteString(`,"type":`) | ||
186 | b.Write(typeJSON) | ||
187 | b.WriteRune('}') | ||
188 | return nil | ||
189 | } | ||