aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/json/value.go
blob: f2f7dd56c775ef4a309d4693311343fe7da56dc7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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)
}