package cty import ( "bytes" "encoding/gob" "fmt" "math/big" ) // GobEncode is an implementation of the gob.GobEncoder interface, which // allows Values to be included in structures encoded with encoding/gob. // // Currently it is not possible to represent values of capsule types in gob, // because the types themselves cannot be represented. func (val Value) GobEncode() ([]byte, error) { buf := &bytes.Buffer{} enc := gob.NewEncoder(buf) gv := gobValue{ Version: 0, Ty: val.ty, V: val.v, } err := enc.Encode(gv) if err != nil { return nil, fmt.Errorf("error encoding cty.Value: %s", err) } return buf.Bytes(), nil } // GobDecode is an implementation of the gob.GobDecoder interface, which // inverts the operation performed by GobEncode. See the documentation of // GobEncode for considerations when using cty.Value instances with gob. func (val *Value) GobDecode(buf []byte) error { r := bytes.NewReader(buf) dec := gob.NewDecoder(r) var gv gobValue err := dec.Decode(&gv) if err != nil { return fmt.Errorf("error decoding cty.Value: %s", err) } if gv.Version != 0 { return fmt.Errorf("unsupported cty.Value encoding version %d; only 0 is supported", gv.Version) } // big.Float seems to, for some reason, lose its "pointerness" when we // round-trip it, so we'll fix that here. if bf, ok := gv.V.(big.Float); ok { gv.V = &bf } val.ty = gv.Ty val.v = gv.V return nil } // GobEncode is an implementation of the gob.GobEncoder interface, which // allows Types to be included in structures encoded with encoding/gob. // // Currently it is not possible to represent capsule types in gob. func (t Type) GobEncode() ([]byte, error) { buf := &bytes.Buffer{} enc := gob.NewEncoder(buf) gt := gobType{ Version: 0, Impl: t.typeImpl, } err := enc.Encode(gt) if err != nil { return nil, fmt.Errorf("error encoding cty.Type: %s", err) } return buf.Bytes(), nil } // GobDecode is an implementatino of the gob.GobDecoder interface, which // reverses the encoding performed by GobEncode to allow types to be recovered // from gob buffers. func (t *Type) GobDecode(buf []byte) error { r := bytes.NewReader(buf) dec := gob.NewDecoder(r) var gt gobType err := dec.Decode(>) if err != nil { return fmt.Errorf("error decoding cty.Type: %s", err) } if gt.Version != 0 { return fmt.Errorf("unsupported cty.Type encoding version %d; only 0 is supported", gt.Version) } t.typeImpl = gt.Impl return nil } // Capsule types cannot currently be gob-encoded, because they rely on pointer // equality and we have no way to recover the original pointer on decode. func (t *capsuleType) GobEncode() ([]byte, error) { return nil, fmt.Errorf("cannot gob-encode capsule type %q", t.FriendlyName(friendlyTypeName)) } func (t *capsuleType) GobDecode() ([]byte, error) { return nil, fmt.Errorf("cannot gob-decode capsule type %q", t.FriendlyName(friendlyTypeName)) } type gobValue struct { Version int Ty Type V interface{} } type gobType struct { Version int Impl typeImpl } type gobCapsuleTypeImpl struct { }