aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/json.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/json.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/json.go176
1 files changed, 176 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/json.go b/vendor/github.com/zclconf/go-cty/cty/json.go
new file mode 100644
index 0000000..c421a62
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/json.go
@@ -0,0 +1,176 @@
1package cty
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7)
8
9// MarshalJSON is an implementation of json.Marshaler that allows Type
10// instances to be serialized as JSON.
11//
12// All standard types can be serialized, but capsule types cannot since there
13// is no way to automatically recover the original pointer and capsule types
14// compare by equality.
15func (t Type) MarshalJSON() ([]byte, error) {
16 switch impl := t.typeImpl.(type) {
17 case primitiveType:
18 switch impl.Kind {
19 case primitiveTypeBool:
20 return []byte{'"', 'b', 'o', 'o', 'l', '"'}, nil
21 case primitiveTypeNumber:
22 return []byte{'"', 'n', 'u', 'm', 'b', 'e', 'r', '"'}, nil
23 case primitiveTypeString:
24 return []byte{'"', 's', 't', 'r', 'i', 'n', 'g', '"'}, nil
25 default:
26 panic("unknown primitive type kind")
27 }
28 case typeList, typeMap, typeSet:
29 buf := &bytes.Buffer{}
30 etyJSON, err := t.ElementType().MarshalJSON()
31 if err != nil {
32 return nil, err
33 }
34 buf.WriteRune('[')
35 switch impl.(type) {
36 case typeList:
37 buf.WriteString(`"list"`)
38 case typeMap:
39 buf.WriteString(`"map"`)
40 case typeSet:
41 buf.WriteString(`"set"`)
42 }
43 buf.WriteRune(',')
44 buf.Write(etyJSON)
45 buf.WriteRune(']')
46 return buf.Bytes(), nil
47 case typeObject:
48 buf := &bytes.Buffer{}
49 atysJSON, err := json.Marshal(t.AttributeTypes())
50 if err != nil {
51 return nil, err
52 }
53 buf.WriteString(`["object",`)
54 buf.Write(atysJSON)
55 buf.WriteRune(']')
56 return buf.Bytes(), nil
57 case typeTuple:
58 buf := &bytes.Buffer{}
59 etysJSON, err := json.Marshal(t.TupleElementTypes())
60 if err != nil {
61 return nil, err
62 }
63 buf.WriteString(`["tuple",`)
64 buf.Write(etysJSON)
65 buf.WriteRune(']')
66 return buf.Bytes(), nil
67 case pseudoTypeDynamic:
68 return []byte{'"', 'd', 'y', 'n', 'a', 'm', 'i', 'c', '"'}, nil
69 case *capsuleType:
70 return nil, fmt.Errorf("type not allowed: %s", t.FriendlyName())
71 default:
72 // should never happen
73 panic("unknown type implementation")
74 }
75}
76
77// UnmarshalJSON is the opposite of MarshalJSON. See the documentation of
78// MarshalJSON for information on the limitations of JSON serialization of
79// types.
80func (t *Type) UnmarshalJSON(buf []byte) error {
81 r := bytes.NewReader(buf)
82 dec := json.NewDecoder(r)
83
84 tok, err := dec.Token()
85 if err != nil {
86 return err
87 }
88
89 switch v := tok.(type) {
90 case string:
91 switch v {
92 case "bool":
93 *t = Bool
94 case "number":
95 *t = Number
96 case "string":
97 *t = String
98 case "dynamic":
99 *t = DynamicPseudoType
100 default:
101 return fmt.Errorf("invalid primitive type name %q", v)
102 }
103
104 if dec.More() {
105 return fmt.Errorf("extraneous data after type description")
106 }
107 return nil
108 case json.Delim:
109 if rune(v) != '[' {
110 return fmt.Errorf("invalid complex type description")
111 }
112
113 tok, err = dec.Token()
114 if err != nil {
115 return err
116 }
117
118 kind, ok := tok.(string)
119 if !ok {
120 return fmt.Errorf("invalid complex type kind name")
121 }
122
123 switch kind {
124 case "list":
125 var ety Type
126 err = dec.Decode(&ety)
127 if err != nil {
128 return err
129 }
130 *t = List(ety)
131 case "map":
132 var ety Type
133 err = dec.Decode(&ety)
134 if err != nil {
135 return err
136 }
137 *t = Map(ety)
138 case "set":
139 var ety Type
140 err = dec.Decode(&ety)
141 if err != nil {
142 return err
143 }
144 *t = Set(ety)
145 case "object":
146 var atys map[string]Type
147 err = dec.Decode(&atys)
148 if err != nil {
149 return err
150 }
151 *t = Object(atys)
152 case "tuple":
153 var etys []Type
154 err = dec.Decode(&etys)
155 if err != nil {
156 return err
157 }
158 *t = Tuple(etys)
159 default:
160 return fmt.Errorf("invalid complex type kind name")
161 }
162
163 tok, err = dec.Token()
164 if err != nil {
165 return err
166 }
167 if delim, ok := tok.(json.Delim); !ok || rune(delim) != ']' || dec.More() {
168 return fmt.Errorf("unexpected extra data in type description")
169 }
170
171 return nil
172
173 default:
174 return fmt.Errorf("invalid type description")
175 }
176}