package json import ( "bytes" "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/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) }