aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/set/gob.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/set/gob.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/set/gob.go76
1 files changed, 76 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/set/gob.go b/vendor/github.com/zclconf/go-cty/cty/set/gob.go
new file mode 100644
index 0000000..da2978f
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/set/gob.go
@@ -0,0 +1,76 @@
1package set
2
3import (
4 "bytes"
5 "encoding/gob"
6 "fmt"
7)
8
9// GobEncode is an implementation of the interface gob.GobEncoder, allowing
10// sets to be included in structures encoded via gob.
11//
12// The set rules are included in the serialized value, so the caller must
13// register its concrete rules type with gob.Register before using a
14// set in a gob, and possibly also implement GobEncode/GobDecode to customize
15// how any parameters are persisted.
16//
17// The set elements are also included, so if they are of non-primitive types
18// they too must be registered with gob.
19//
20// If the produced gob values will persist for a long time, the caller must
21// ensure compatibility of the rules implementation. In particular, if the
22// definition of element equivalence changes between encoding and decoding
23// then two distinct stored elements may be considered equivalent on decoding,
24// causing the recovered set to have fewer elements than when it was stored.
25func (s Set) GobEncode() ([]byte, error) {
26 gs := gobSet{
27 Version: 0,
28 Rules: s.rules,
29 Values: s.Values(),
30 }
31
32 buf := &bytes.Buffer{}
33 enc := gob.NewEncoder(buf)
34 err := enc.Encode(gs)
35 if err != nil {
36 return nil, fmt.Errorf("error encoding set.Set: %s", err)
37 }
38
39 return buf.Bytes(), nil
40}
41
42// GobDecode is the opposite of GobEncode. See GobEncode for information
43// on the requirements for and caveats of including set values in gobs.
44func (s *Set) GobDecode(buf []byte) error {
45 r := bytes.NewReader(buf)
46 dec := gob.NewDecoder(r)
47
48 var gs gobSet
49 err := dec.Decode(&gs)
50 if err != nil {
51 return fmt.Errorf("error decoding set.Set: %s", err)
52 }
53 if gs.Version != 0 {
54 return fmt.Errorf("unsupported set.Set encoding version %d; need 0", gs.Version)
55 }
56
57 victim := NewSetFromSlice(gs.Rules, gs.Values)
58 s.vals = victim.vals
59 s.rules = victim.rules
60 return nil
61}
62
63type gobSet struct {
64 Version int
65 Rules Rules
66
67 // The bucket-based representation is for efficient in-memory access, but
68 // for serialization it's enough to just retain the values themselves,
69 // which we can re-bucket using the rules (which may have changed!) when
70 // we re-inflate.
71 Values []interface{}
72}
73
74func init() {
75 gob.Register([]interface{}(nil))
76}