diff options
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.go | 76 |
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 @@ | |||
1 | package set | ||
2 | |||
3 | import ( | ||
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. | ||
25 | func (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. | ||
44 | func (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 | |||
63 | type 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 | |||
74 | func init() { | ||
75 | gob.Register([]interface{}(nil)) | ||
76 | } | ||