]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/plans/dynamic_value.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / plans / dynamic_value.go
1 package plans
2
3 import (
4 "github.com/zclconf/go-cty/cty"
5 ctymsgpack "github.com/zclconf/go-cty/cty/msgpack"
6 )
7
8 // DynamicValue is the representation in the plan of a value whose type cannot
9 // be determined at compile time, such as because it comes from a schema
10 // defined in a plugin.
11 //
12 // This type is used as an indirection so that the overall plan structure can
13 // be decoded without schema available, and then the dynamic values accessed
14 // at a later time once the appropriate schema has been determined.
15 //
16 // Internally, DynamicValue is a serialized version of a cty.Value created
17 // against a particular type constraint. Callers should not access directly
18 // the serialized form, whose format may change in future. Values of this
19 // type must always be created by calling NewDynamicValue.
20 //
21 // The zero value of DynamicValue is nil, and represents the absense of a
22 // value within the Go type system. This is distinct from a cty.NullVal
23 // result, which represents the absense of a value within the cty type system.
24 type DynamicValue []byte
25
26 // NewDynamicValue creates a DynamicValue by serializing the given value
27 // against the given type constraint. The value must conform to the type
28 // constraint, or the result is undefined.
29 //
30 // If the value to be encoded has no predefined schema (for example, for
31 // module output values and input variables), set the type constraint to
32 // cty.DynamicPseudoType in order to save type information as part of the
33 // value, and then also pass cty.DynamicPseudoType to method Decode to recover
34 // the original value.
35 //
36 // cty.NilVal can be used to represent the absense of a value, but callers
37 // must be careful to distinguish values that are absent at the Go layer
38 // (cty.NilVal) vs. values that are absent at the cty layer (cty.NullVal
39 // results).
40 func NewDynamicValue(val cty.Value, ty cty.Type) (DynamicValue, error) {
41 // If we're given cty.NilVal (the zero value of cty.Value, which is
42 // distinct from a typed null value created by cty.NullVal) then we'll
43 // assume the caller is trying to represent the _absense_ of a value,
44 // and so we'll return a nil DynamicValue.
45 if val == cty.NilVal {
46 return DynamicValue(nil), nil
47 }
48
49 // Currently our internal encoding is msgpack, via ctymsgpack.
50 buf, err := ctymsgpack.Marshal(val, ty)
51 if err != nil {
52 return nil, err
53 }
54
55 return DynamicValue(buf), nil
56 }
57
58 // Decode retrieves the effective value from the receiever by interpreting the
59 // serialized form against the given type constraint. For correct results,
60 // the type constraint must match (or be consistent with) the one that was
61 // used to create the receiver.
62 //
63 // A nil DynamicValue decodes to cty.NilVal, which is not a valid value and
64 // instead represents the absense of a value.
65 func (v DynamicValue) Decode(ty cty.Type) (cty.Value, error) {
66 if v == nil {
67 return cty.NilVal, nil
68 }
69
70 return ctymsgpack.Unmarshal([]byte(v), ty)
71 }
72
73 // ImpliedType returns the type implied by the serialized structure of the
74 // receiving value.
75 //
76 // This will not necessarily be exactly the type that was given when the
77 // value was encoded, and in particular must not be used for values that
78 // were encoded with their static type given as cty.DynamicPseudoType.
79 // It is however safe to use this method for values that were encoded using
80 // their runtime type as the conforming type, with the result being
81 // semantically equivalent but with all lists and sets represented as tuples,
82 // and maps as objects, due to ambiguities of the serialization.
83 func (v DynamicValue) ImpliedType() (cty.Type, error) {
84 return ctymsgpack.ImpliedType([]byte(v))
85 }
86
87 // Copy produces a copy of the receiver with a distinct backing array.
88 func (v DynamicValue) Copy() DynamicValue {
89 if v == nil {
90 return nil
91 }
92
93 ret := make(DynamicValue, len(v))
94 copy(ret, v)
95 return ret
96 }