add vendor
This commit is contained in:
11
vendor/github.com/zclconf/go-cty/cty/json/doc.go
generated
vendored
Normal file
11
vendor/github.com/zclconf/go-cty/cty/json/doc.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// Package json provides functions for serializing cty types and values in
|
||||
// JSON format, and for decoding them again.
|
||||
//
|
||||
// Since the cty type system is a superset of the JSON type system,
|
||||
// round-tripping through JSON is lossy unless type information is provided
|
||||
// both at encoding time and decoding time. Callers of this package are
|
||||
// therefore suggested to define their expected structure as a cty.Type
|
||||
// and pass it in consistently both when encoding and when decoding, though
|
||||
// default (type-lossy) behavior is provided for situations where the precise
|
||||
// representation of the data is not significant.
|
||||
package json
|
193
vendor/github.com/zclconf/go-cty/cty/json/marshal.go
generated
vendored
Normal file
193
vendor/github.com/zclconf/go-cty/cty/json/marshal.go
generated
vendored
Normal file
@ -0,0 +1,193 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"sort"
|
||||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
func marshal(val cty.Value, t cty.Type, path cty.Path, b *bytes.Buffer) error {
|
||||
if val.IsMarked() {
|
||||
return path.NewErrorf("value has marks, so it cannot be serialized as JSON")
|
||||
}
|
||||
|
||||
// If we're going to decode as DynamicPseudoType then we need to save
|
||||
// dynamic type information to recover the real type.
|
||||
if t == cty.DynamicPseudoType && val.Type() != cty.DynamicPseudoType {
|
||||
return marshalDynamic(val, path, b)
|
||||
}
|
||||
|
||||
if val.IsNull() {
|
||||
b.WriteString("null")
|
||||
return nil
|
||||
}
|
||||
|
||||
if !val.IsKnown() {
|
||||
return path.NewErrorf("value is not known")
|
||||
}
|
||||
|
||||
// The caller should've guaranteed that the given val is conformant with
|
||||
// the given type t, so we'll proceed under that assumption here.
|
||||
|
||||
switch {
|
||||
case t.IsPrimitiveType():
|
||||
switch t {
|
||||
case cty.String:
|
||||
json, err := json.Marshal(val.AsString())
|
||||
if err != nil {
|
||||
return path.NewErrorf("failed to serialize value: %s", err)
|
||||
}
|
||||
b.Write(json)
|
||||
return nil
|
||||
case cty.Number:
|
||||
if val.RawEquals(cty.PositiveInfinity) || val.RawEquals(cty.NegativeInfinity) {
|
||||
return path.NewErrorf("cannot serialize infinity as JSON")
|
||||
}
|
||||
b.WriteString(val.AsBigFloat().Text('f', -1))
|
||||
return nil
|
||||
case cty.Bool:
|
||||
if val.True() {
|
||||
b.WriteString("true")
|
||||
} else {
|
||||
b.WriteString("false")
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
panic("unsupported primitive type")
|
||||
}
|
||||
case t.IsListType(), t.IsSetType():
|
||||
b.WriteRune('[')
|
||||
first := true
|
||||
ety := t.ElementType()
|
||||
it := val.ElementIterator()
|
||||
path := append(path, nil) // local override of 'path' with extra element
|
||||
for it.Next() {
|
||||
if !first {
|
||||
b.WriteRune(',')
|
||||
}
|
||||
ek, ev := it.Element()
|
||||
path[len(path)-1] = cty.IndexStep{
|
||||
Key: ek,
|
||||
}
|
||||
err := marshal(ev, ety, path, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
first = false
|
||||
}
|
||||
b.WriteRune(']')
|
||||
return nil
|
||||
case t.IsMapType():
|
||||
b.WriteRune('{')
|
||||
first := true
|
||||
ety := t.ElementType()
|
||||
it := val.ElementIterator()
|
||||
path := append(path, nil) // local override of 'path' with extra element
|
||||
for it.Next() {
|
||||
if !first {
|
||||
b.WriteRune(',')
|
||||
}
|
||||
ek, ev := it.Element()
|
||||
path[len(path)-1] = cty.IndexStep{
|
||||
Key: ek,
|
||||
}
|
||||
var err error
|
||||
err = marshal(ek, ek.Type(), path, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.WriteRune(':')
|
||||
err = marshal(ev, ety, path, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
first = false
|
||||
}
|
||||
b.WriteRune('}')
|
||||
return nil
|
||||
case t.IsTupleType():
|
||||
b.WriteRune('[')
|
||||
etys := t.TupleElementTypes()
|
||||
it := val.ElementIterator()
|
||||
path := append(path, nil) // local override of 'path' with extra element
|
||||
i := 0
|
||||
for it.Next() {
|
||||
if i > 0 {
|
||||
b.WriteRune(',')
|
||||
}
|
||||
ety := etys[i]
|
||||
ek, ev := it.Element()
|
||||
path[len(path)-1] = cty.IndexStep{
|
||||
Key: ek,
|
||||
}
|
||||
err := marshal(ev, ety, path, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i++
|
||||
}
|
||||
b.WriteRune(']')
|
||||
return nil
|
||||
case t.IsObjectType():
|
||||
b.WriteRune('{')
|
||||
atys := t.AttributeTypes()
|
||||
path := append(path, nil) // local override of 'path' with extra element
|
||||
|
||||
names := make([]string, 0, len(atys))
|
||||
for k := range atys {
|
||||
names = append(names, k)
|
||||
}
|
||||
sort.Strings(names)
|
||||
|
||||
for i, k := range names {
|
||||
aty := atys[k]
|
||||
if i > 0 {
|
||||
b.WriteRune(',')
|
||||
}
|
||||
av := val.GetAttr(k)
|
||||
path[len(path)-1] = cty.GetAttrStep{
|
||||
Name: k,
|
||||
}
|
||||
var err error
|
||||
err = marshal(cty.StringVal(k), cty.String, path, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.WriteRune(':')
|
||||
err = marshal(av, aty, path, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
b.WriteRune('}')
|
||||
return nil
|
||||
case t.IsCapsuleType():
|
||||
rawVal := val.EncapsulatedValue()
|
||||
jsonVal, err := json.Marshal(rawVal)
|
||||
if err != nil {
|
||||
return path.NewError(err)
|
||||
}
|
||||
b.Write(jsonVal)
|
||||
return nil
|
||||
default:
|
||||
// should never happen
|
||||
return path.NewErrorf("cannot JSON-serialize %s", t.FriendlyName())
|
||||
}
|
||||
}
|
||||
|
||||
// marshalDynamic adds an extra wrapping object containing dynamic type
|
||||
// information for the given value.
|
||||
func marshalDynamic(val cty.Value, path cty.Path, b *bytes.Buffer) error {
|
||||
typeJSON, err := MarshalType(val.Type())
|
||||
if err != nil {
|
||||
return path.NewErrorf("failed to serialize type: %s", err)
|
||||
}
|
||||
b.WriteString(`{"value":`)
|
||||
marshal(val, val.Type(), path, b)
|
||||
b.WriteString(`,"type":`)
|
||||
b.Write(typeJSON)
|
||||
b.WriteRune('}')
|
||||
return nil
|
||||
}
|
41
vendor/github.com/zclconf/go-cty/cty/json/simple.go
generated
vendored
Normal file
41
vendor/github.com/zclconf/go-cty/cty/json/simple.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// SimpleJSONValue is a wrapper around cty.Value that adds implementations of
|
||||
// json.Marshaler and json.Unmarshaler for simple-but-type-lossy automatic
|
||||
// encoding and decoding of values.
|
||||
//
|
||||
// The couplet Marshal and Unmarshal both take extra type information to
|
||||
// inform the encoding and decoding process so that all of the cty types
|
||||
// can be represented even though JSON's type system is a subset.
|
||||
//
|
||||
// SimpleJSONValue instead takes the approach of discarding the value's type
|
||||
// information and then deriving a new type from the stored structure when
|
||||
// decoding. This results in the same data being returned but not necessarily
|
||||
// with exactly the same type.
|
||||
//
|
||||
// For information on how types are inferred when decoding, see the
|
||||
// documentation of the function ImpliedType.
|
||||
type SimpleJSONValue struct {
|
||||
cty.Value
|
||||
}
|
||||
|
||||
// MarshalJSON is an implementation of json.Marshaler. See the documentation
|
||||
// of SimpleJSONValue for more information.
|
||||
func (v SimpleJSONValue) MarshalJSON() ([]byte, error) {
|
||||
return Marshal(v.Value, v.Type())
|
||||
}
|
||||
|
||||
// UnmarshalJSON is an implementation of json.Unmarshaler. See the
|
||||
// documentation of SimpleJSONValue for more information.
|
||||
func (v *SimpleJSONValue) UnmarshalJSON(buf []byte) error {
|
||||
t, err := ImpliedType(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Value, err = Unmarshal(buf, t)
|
||||
return err
|
||||
}
|
23
vendor/github.com/zclconf/go-cty/cty/json/type.go
generated
vendored
Normal file
23
vendor/github.com/zclconf/go-cty/cty/json/type.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// MarshalType returns a JSON serialization of the given type.
|
||||
//
|
||||
// This is just a thin wrapper around t.MarshalJSON, for symmetry with
|
||||
// UnmarshalType.
|
||||
func MarshalType(t cty.Type) ([]byte, error) {
|
||||
return t.MarshalJSON()
|
||||
}
|
||||
|
||||
// UnmarshalType decodes a JSON serialization of the given type as produced
|
||||
// by either Type.MarshalJSON or MarshalType.
|
||||
//
|
||||
// This is a convenience wrapper around Type.UnmarshalJSON.
|
||||
func UnmarshalType(buf []byte) (cty.Type, error) {
|
||||
var t cty.Type
|
||||
err := t.UnmarshalJSON(buf)
|
||||
return t, err
|
||||
}
|
170
vendor/github.com/zclconf/go-cty/cty/json/type_implied.go
generated
vendored
Normal file
170
vendor/github.com/zclconf/go-cty/cty/json/type_implied.go
generated
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
// ImpliedType returns the cty Type implied by the structure of the given
|
||||
// JSON-compliant buffer. This function implements the default type mapping
|
||||
// behavior used when decoding arbitrary JSON without explicit cty Type
|
||||
// information.
|
||||
//
|
||||
// The rules are as follows:
|
||||
//
|
||||
// JSON strings, numbers and bools map to their equivalent primitive type in
|
||||
// cty.
|
||||
//
|
||||
// JSON objects map to cty object types, with the attributes defined by the
|
||||
// object keys and the types of their values.
|
||||
//
|
||||
// JSON arrays map to cty tuple types, with the elements defined by the
|
||||
// types of the array members.
|
||||
//
|
||||
// Any nulls are typed as DynamicPseudoType, so callers of this function
|
||||
// must be prepared to deal with this. Callers that do not wish to deal with
|
||||
// dynamic typing should not use this function and should instead describe
|
||||
// their required types explicitly with a cty.Type instance when decoding.
|
||||
//
|
||||
// Any JSON syntax errors will be returned as an error, and the type will
|
||||
// be the invalid value cty.NilType.
|
||||
func ImpliedType(buf []byte) (cty.Type, error) {
|
||||
r := bytes.NewReader(buf)
|
||||
dec := json.NewDecoder(r)
|
||||
dec.UseNumber()
|
||||
|
||||
ty, err := impliedType(dec)
|
||||
if err != nil {
|
||||
return cty.NilType, err
|
||||
}
|
||||
|
||||
if dec.More() {
|
||||
return cty.NilType, fmt.Errorf("extraneous data after JSON object")
|
||||
}
|
||||
|
||||
return ty, nil
|
||||
}
|
||||
|
||||
func impliedType(dec *json.Decoder) (cty.Type, error) {
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return cty.NilType, err
|
||||
}
|
||||
|
||||
return impliedTypeForTok(tok, dec)
|
||||
}
|
||||
|
||||
func impliedTypeForTok(tok json.Token, dec *json.Decoder) (cty.Type, error) {
|
||||
if tok == nil {
|
||||
return cty.DynamicPseudoType, nil
|
||||
}
|
||||
|
||||
switch ttok := tok.(type) {
|
||||
case bool:
|
||||
return cty.Bool, nil
|
||||
|
||||
case json.Number:
|
||||
return cty.Number, nil
|
||||
|
||||
case string:
|
||||
return cty.String, nil
|
||||
|
||||
case json.Delim:
|
||||
|
||||
switch rune(ttok) {
|
||||
case '{':
|
||||
return impliedObjectType(dec)
|
||||
case '[':
|
||||
return impliedTupleType(dec)
|
||||
default:
|
||||
return cty.NilType, fmt.Errorf("unexpected token %q", ttok)
|
||||
}
|
||||
|
||||
default:
|
||||
return cty.NilType, fmt.Errorf("unsupported JSON token %#v", tok)
|
||||
}
|
||||
}
|
||||
|
||||
func impliedObjectType(dec *json.Decoder) (cty.Type, error) {
|
||||
// By the time we get in here, we've already consumed the { delimiter
|
||||
// and so our next token should be the first object key.
|
||||
|
||||
var atys map[string]cty.Type
|
||||
|
||||
for {
|
||||
// Read the object key first
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return cty.NilType, err
|
||||
}
|
||||
|
||||
if ttok, ok := tok.(json.Delim); ok {
|
||||
if rune(ttok) != '}' {
|
||||
return cty.NilType, fmt.Errorf("unexpected delimiter %q", ttok)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
key, ok := tok.(string)
|
||||
if !ok {
|
||||
return cty.NilType, fmt.Errorf("expected string but found %T", tok)
|
||||
}
|
||||
|
||||
// Now read the value
|
||||
tok, err = dec.Token()
|
||||
if err != nil {
|
||||
return cty.NilType, err
|
||||
}
|
||||
|
||||
aty, err := impliedTypeForTok(tok, dec)
|
||||
if err != nil {
|
||||
return cty.NilType, err
|
||||
}
|
||||
|
||||
if atys == nil {
|
||||
atys = make(map[string]cty.Type)
|
||||
}
|
||||
atys[key] = aty
|
||||
}
|
||||
|
||||
if len(atys) == 0 {
|
||||
return cty.EmptyObject, nil
|
||||
}
|
||||
|
||||
return cty.Object(atys), nil
|
||||
}
|
||||
|
||||
func impliedTupleType(dec *json.Decoder) (cty.Type, error) {
|
||||
// By the time we get in here, we've already consumed the [ delimiter
|
||||
// and so our next token should be the first value.
|
||||
|
||||
var etys []cty.Type
|
||||
|
||||
for {
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return cty.NilType, err
|
||||
}
|
||||
|
||||
if ttok, ok := tok.(json.Delim); ok {
|
||||
if rune(ttok) == ']' {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
ety, err := impliedTypeForTok(tok, dec)
|
||||
if err != nil {
|
||||
return cty.NilType, err
|
||||
}
|
||||
etys = append(etys, ety)
|
||||
}
|
||||
|
||||
if len(etys) == 0 {
|
||||
return cty.EmptyTuple, nil
|
||||
}
|
||||
|
||||
return cty.Tuple(etys), nil
|
||||
}
|
459
vendor/github.com/zclconf/go-cty/cty/json/unmarshal.go
generated
vendored
Normal file
459
vendor/github.com/zclconf/go-cty/cty/json/unmarshal.go
generated
vendored
Normal file
@ -0,0 +1,459 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/convert"
|
||||
)
|
||||
|
||||
func unmarshal(buf []byte, t cty.Type, path cty.Path) (cty.Value, error) {
|
||||
dec := bufDecoder(buf)
|
||||
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
if tok == nil {
|
||||
return cty.NullVal(t), nil
|
||||
}
|
||||
|
||||
if t == cty.DynamicPseudoType {
|
||||
return unmarshalDynamic(buf, path)
|
||||
}
|
||||
|
||||
switch {
|
||||
case t.IsPrimitiveType():
|
||||
val, err := unmarshalPrimitive(tok, t, path)
|
||||
if err != nil {
|
||||
return cty.NilVal, err
|
||||
}
|
||||
return val, nil
|
||||
case t.IsListType():
|
||||
return unmarshalList(buf, t.ElementType(), path)
|
||||
case t.IsSetType():
|
||||
return unmarshalSet(buf, t.ElementType(), path)
|
||||
case t.IsMapType():
|
||||
return unmarshalMap(buf, t.ElementType(), path)
|
||||
case t.IsTupleType():
|
||||
return unmarshalTuple(buf, t.TupleElementTypes(), path)
|
||||
case t.IsObjectType():
|
||||
return unmarshalObject(buf, t.AttributeTypes(), path)
|
||||
case t.IsCapsuleType():
|
||||
return unmarshalCapsule(buf, t, path)
|
||||
default:
|
||||
return cty.NilVal, path.NewErrorf("unsupported type %s", t.FriendlyName())
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalPrimitive(tok json.Token, t cty.Type, path cty.Path) (cty.Value, error) {
|
||||
|
||||
switch t {
|
||||
case cty.Bool:
|
||||
switch v := tok.(type) {
|
||||
case bool:
|
||||
return cty.BoolVal(v), nil
|
||||
case string:
|
||||
val, err := convert.Convert(cty.StringVal(v), t)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
return val, nil
|
||||
default:
|
||||
return cty.NilVal, path.NewErrorf("bool is required")
|
||||
}
|
||||
case cty.Number:
|
||||
if v, ok := tok.(json.Number); ok {
|
||||
tok = string(v)
|
||||
}
|
||||
switch v := tok.(type) {
|
||||
case string:
|
||||
val, err := cty.ParseNumberVal(v)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
return val, nil
|
||||
default:
|
||||
return cty.NilVal, path.NewErrorf("number is required")
|
||||
}
|
||||
case cty.String:
|
||||
switch v := tok.(type) {
|
||||
case string:
|
||||
return cty.StringVal(v), nil
|
||||
case json.Number:
|
||||
return cty.StringVal(string(v)), nil
|
||||
case bool:
|
||||
val, err := convert.Convert(cty.BoolVal(v), t)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
return val, nil
|
||||
default:
|
||||
return cty.NilVal, path.NewErrorf("string is required")
|
||||
}
|
||||
default:
|
||||
// should never happen
|
||||
panic("unsupported primitive type")
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalList(buf []byte, ety cty.Type, path cty.Path) (cty.Value, error) {
|
||||
dec := bufDecoder(buf)
|
||||
if err := requireDelim(dec, '['); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
var vals []cty.Value
|
||||
|
||||
{
|
||||
path := append(path, nil)
|
||||
var idx int64
|
||||
|
||||
for dec.More() {
|
||||
path[len(path)-1] = cty.IndexStep{
|
||||
Key: cty.NumberIntVal(idx),
|
||||
}
|
||||
idx++
|
||||
|
||||
rawVal, err := readRawValue(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read list value: %s", err)
|
||||
}
|
||||
|
||||
el, err := unmarshal(rawVal, ety, path)
|
||||
if err != nil {
|
||||
return cty.NilVal, err
|
||||
}
|
||||
|
||||
vals = append(vals, el)
|
||||
}
|
||||
}
|
||||
|
||||
if err := requireDelim(dec, ']'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
if len(vals) == 0 {
|
||||
return cty.ListValEmpty(ety), nil
|
||||
}
|
||||
|
||||
return cty.ListVal(vals), nil
|
||||
}
|
||||
|
||||
func unmarshalSet(buf []byte, ety cty.Type, path cty.Path) (cty.Value, error) {
|
||||
dec := bufDecoder(buf)
|
||||
if err := requireDelim(dec, '['); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
var vals []cty.Value
|
||||
|
||||
{
|
||||
path := append(path, nil)
|
||||
|
||||
for dec.More() {
|
||||
path[len(path)-1] = cty.IndexStep{
|
||||
Key: cty.UnknownVal(ety),
|
||||
}
|
||||
|
||||
rawVal, err := readRawValue(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read set value: %s", err)
|
||||
}
|
||||
|
||||
el, err := unmarshal(rawVal, ety, path)
|
||||
if err != nil {
|
||||
return cty.NilVal, err
|
||||
}
|
||||
|
||||
vals = append(vals, el)
|
||||
}
|
||||
}
|
||||
|
||||
if err := requireDelim(dec, ']'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
if len(vals) == 0 {
|
||||
return cty.SetValEmpty(ety), nil
|
||||
}
|
||||
|
||||
return cty.SetVal(vals), nil
|
||||
}
|
||||
|
||||
func unmarshalMap(buf []byte, ety cty.Type, path cty.Path) (cty.Value, error) {
|
||||
dec := bufDecoder(buf)
|
||||
if err := requireDelim(dec, '{'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
vals := make(map[string]cty.Value)
|
||||
|
||||
{
|
||||
path := append(path, nil)
|
||||
|
||||
for dec.More() {
|
||||
path[len(path)-1] = cty.IndexStep{
|
||||
Key: cty.UnknownVal(cty.String),
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
k, err := requireObjectKey(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read map key: %s", err)
|
||||
}
|
||||
|
||||
path[len(path)-1] = cty.IndexStep{
|
||||
Key: cty.StringVal(k),
|
||||
}
|
||||
|
||||
rawVal, err := readRawValue(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read map value: %s", err)
|
||||
}
|
||||
|
||||
el, err := unmarshal(rawVal, ety, path)
|
||||
if err != nil {
|
||||
return cty.NilVal, err
|
||||
}
|
||||
|
||||
vals[k] = el
|
||||
}
|
||||
}
|
||||
|
||||
if err := requireDelim(dec, '}'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
if len(vals) == 0 {
|
||||
return cty.MapValEmpty(ety), nil
|
||||
}
|
||||
|
||||
return cty.MapVal(vals), nil
|
||||
}
|
||||
|
||||
func unmarshalTuple(buf []byte, etys []cty.Type, path cty.Path) (cty.Value, error) {
|
||||
dec := bufDecoder(buf)
|
||||
if err := requireDelim(dec, '['); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
var vals []cty.Value
|
||||
|
||||
{
|
||||
path := append(path, nil)
|
||||
var idx int
|
||||
|
||||
for dec.More() {
|
||||
if idx >= len(etys) {
|
||||
return cty.NilVal, path[:len(path)-1].NewErrorf("too many tuple elements (need %d)", len(etys))
|
||||
}
|
||||
|
||||
path[len(path)-1] = cty.IndexStep{
|
||||
Key: cty.NumberIntVal(int64(idx)),
|
||||
}
|
||||
ety := etys[idx]
|
||||
idx++
|
||||
|
||||
rawVal, err := readRawValue(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read tuple value: %s", err)
|
||||
}
|
||||
|
||||
el, err := unmarshal(rawVal, ety, path)
|
||||
if err != nil {
|
||||
return cty.NilVal, err
|
||||
}
|
||||
|
||||
vals = append(vals, el)
|
||||
}
|
||||
}
|
||||
|
||||
if err := requireDelim(dec, ']'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
if len(vals) != len(etys) {
|
||||
return cty.NilVal, path[:len(path)-1].NewErrorf("not enough tuple elements (need %d)", len(etys))
|
||||
}
|
||||
|
||||
if len(vals) == 0 {
|
||||
return cty.EmptyTupleVal, nil
|
||||
}
|
||||
|
||||
return cty.TupleVal(vals), nil
|
||||
}
|
||||
|
||||
func unmarshalObject(buf []byte, atys map[string]cty.Type, path cty.Path) (cty.Value, error) {
|
||||
dec := bufDecoder(buf)
|
||||
if err := requireDelim(dec, '{'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
vals := make(map[string]cty.Value)
|
||||
|
||||
{
|
||||
objPath := path // some errors report from the object's perspective
|
||||
path := append(path, nil) // path to a specific attribute
|
||||
|
||||
for dec.More() {
|
||||
|
||||
var err error
|
||||
|
||||
k, err := requireObjectKey(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read object key: %s", err)
|
||||
}
|
||||
|
||||
aty, ok := atys[k]
|
||||
if !ok {
|
||||
return cty.NilVal, objPath.NewErrorf("unsupported attribute %q", k)
|
||||
}
|
||||
|
||||
path[len(path)-1] = cty.GetAttrStep{
|
||||
Name: k,
|
||||
}
|
||||
|
||||
rawVal, err := readRawValue(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read object value: %s", err)
|
||||
}
|
||||
|
||||
el, err := unmarshal(rawVal, aty, path)
|
||||
if err != nil {
|
||||
return cty.NilVal, err
|
||||
}
|
||||
|
||||
vals[k] = el
|
||||
}
|
||||
}
|
||||
|
||||
if err := requireDelim(dec, '}'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
// Make sure we have a value for every attribute
|
||||
for k, aty := range atys {
|
||||
if _, exists := vals[k]; !exists {
|
||||
vals[k] = cty.NullVal(aty)
|
||||
}
|
||||
}
|
||||
|
||||
if len(vals) == 0 {
|
||||
return cty.EmptyObjectVal, nil
|
||||
}
|
||||
|
||||
return cty.ObjectVal(vals), nil
|
||||
}
|
||||
|
||||
func unmarshalCapsule(buf []byte, t cty.Type, path cty.Path) (cty.Value, error) {
|
||||
rawType := t.EncapsulatedType()
|
||||
ptrPtr := reflect.New(reflect.PtrTo(rawType))
|
||||
ptrPtr.Elem().Set(reflect.New(rawType))
|
||||
ptr := ptrPtr.Elem().Interface()
|
||||
err := json.Unmarshal(buf, ptr)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
return cty.CapsuleVal(t, ptr), nil
|
||||
}
|
||||
|
||||
func unmarshalDynamic(buf []byte, path cty.Path) (cty.Value, error) {
|
||||
dec := bufDecoder(buf)
|
||||
if err := requireDelim(dec, '{'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
var t cty.Type
|
||||
var valBody []byte // defer actual decoding until we know the type
|
||||
|
||||
for dec.More() {
|
||||
var err error
|
||||
|
||||
key, err := requireObjectKey(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read dynamic type descriptor key: %s", err)
|
||||
}
|
||||
|
||||
rawVal, err := readRawValue(dec)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to read dynamic type descriptor value: %s", err)
|
||||
}
|
||||
|
||||
switch key {
|
||||
case "type":
|
||||
err := json.Unmarshal(rawVal, &t)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewErrorf("failed to decode type for dynamic value: %s", err)
|
||||
}
|
||||
case "value":
|
||||
valBody = rawVal
|
||||
default:
|
||||
return cty.NilVal, path.NewErrorf("invalid key %q in dynamically-typed value", key)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if err := requireDelim(dec, '}'); err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
|
||||
if t == cty.NilType {
|
||||
return cty.NilVal, path.NewErrorf("missing type in dynamically-typed value")
|
||||
}
|
||||
if valBody == nil {
|
||||
return cty.NilVal, path.NewErrorf("missing value in dynamically-typed value")
|
||||
}
|
||||
|
||||
val, err := Unmarshal([]byte(valBody), t)
|
||||
if err != nil {
|
||||
return cty.NilVal, path.NewError(err)
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func requireDelim(dec *json.Decoder, d rune) error {
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tok != json.Delim(d) {
|
||||
return fmt.Errorf("missing expected %c", d)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func requireObjectKey(dec *json.Decoder) (string, error) {
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if s, ok := tok.(string); ok {
|
||||
return s, nil
|
||||
}
|
||||
return "", fmt.Errorf("missing expected object key")
|
||||
}
|
||||
|
||||
func readRawValue(dec *json.Decoder) ([]byte, error) {
|
||||
var rawVal json.RawMessage
|
||||
err := dec.Decode(&rawVal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []byte(rawVal), nil
|
||||
}
|
||||
|
||||
func bufDecoder(buf []byte) *json.Decoder {
|
||||
r := bytes.NewReader(buf)
|
||||
dec := json.NewDecoder(r)
|
||||
dec.UseNumber()
|
||||
return dec
|
||||
}
|
65
vendor/github.com/zclconf/go-cty/cty/json/value.go
generated
vendored
Normal file
65
vendor/github.com/zclconf/go-cty/cty/json/value.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/convert"
|
||||
)
|
||||
|
||||
// Marshal produces a JSON representation of the given value that can later
|
||||
// be decoded into a value of the given type.
|
||||
//
|
||||
// A type is specified separately to allow for the given type to include
|
||||
// cty.DynamicPseudoType to represent situations where any type is permitted
|
||||
// and so type information must be included to allow recovery of the stored
|
||||
// structure when decoding.
|
||||
//
|
||||
// The given type will also be used to attempt automatic conversions of any
|
||||
// non-conformant types in the given value, although this will not always
|
||||
// be possible. If the value cannot be made to be conformant then an error is
|
||||
// returned, which may be a cty.PathError.
|
||||
//
|
||||
// Capsule-typed values can be marshalled, but with some caveats. Since
|
||||
// capsule values are compared by pointer equality, it is impossible to recover
|
||||
// a value that will compare equal to the original value. Additionally,
|
||||
// it's not possible to JSON-serialize the capsule type itself, so it's not
|
||||
// valid to use capsule types within parts of the value that are conformed to
|
||||
// cty.DynamicPseudoType. Otherwise, a capsule value can be used as long as
|
||||
// the encapsulated type itself is serializable with the Marshal function
|
||||
// in encoding/json.
|
||||
func Marshal(val cty.Value, t cty.Type) ([]byte, error) {
|
||||
errs := val.Type().TestConformance(t)
|
||||
if errs != nil {
|
||||
// Attempt a conversion
|
||||
var err error
|
||||
val, err = convert.Convert(val, t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// From this point onward, val can be assumed to be conforming to t.
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
var path cty.Path
|
||||
err := marshal(val, t, path, buf)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// Unmarshal decodes a JSON representation of the given value into a cty Value
|
||||
// conforming to the given type.
|
||||
//
|
||||
// While decoding, type conversions will be done where possible to make
|
||||
// the result conformant even if the types given in JSON are not exactly
|
||||
// correct. If conversion isn't possible then an error is returned, which
|
||||
// may be a cty.PathError.
|
||||
func Unmarshal(buf []byte, t cty.Type) (cty.Value, error) {
|
||||
var path cty.Path
|
||||
return unmarshal(buf, t, path)
|
||||
}
|
Reference in New Issue
Block a user