OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / go-wire / data / docs.go
1 /*
2 Data is designed to provide a standard interface and helper functions to
3 easily allow serialization and deserialization of your data structures
4 in both binary and json representations.
5
6 This is commonly needed for interpreting transactions or stored data in the
7 abci app, as well as accepting json input in the light-client proxy. If we
8 can standardize how we pass data around the app, we can also allow more
9 extensions, like data storage that can interpret the meaning of the []byte
10 passed in, and use that to index multiple fields for example.
11
12 Serialization of data is pretty automatic using standard json and go-wire
13 encoders.  The main issue is deserialization, especially when using interfaces
14 where there are many possible concrete types.
15
16 go-wire handles this by registering the types and providing a custom
17 deserializer:
18
19   var _ = wire.RegisterInterface(
20     struct{ PubKey }{},
21     wire.ConcreteType{PubKeyEd25519{}, PubKeyTypeEd25519},
22     wire.ConcreteType{PubKeySecp256k1{}, PubKeyTypeSecp256k1},
23   )
24
25   func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) {
26     err = wire.ReadBinaryBytes(pubKeyBytes, &pubKey)
27     return
28   }
29
30   func (pubKey PubKeyEd25519) Bytes() []byte {
31     return wire.BinaryBytes(struct{ PubKey }{pubKey})
32   }
33
34 This prepends a type-byte to the binary representation upon serialization and
35 using that byte to switch between various representations on deserialization.
36 go-wire also supports something similar in json, but it leads to kind of ugly
37 mixed-types arrays, and requires using the go-wire json parser, which is
38 limited relative to the standard library encoding/json library.
39
40 In json, the typical idiom is to use a type string and message data:
41
42   {
43     "type": "this part tells you how to interpret the message",
44     "data": ...the actual message is here, in some kind of json...
45   }
46
47 I took inspiration from two blog posts, that demonstrate how to use this
48 to build (de)serialization in a go-wire like way.
49
50 * http://eagain.net/articles/go-dynamic-json/
51 * http://eagain.net/articles/go-json-kind/
52
53 This package unifies these two in a single Mapper.
54
55 You app needs to do three things to take full advantage of this:
56
57 1. For every interface you wish to serialize, define a holder struct with some helper methods, like FooerS wraps Fooer in common_test.go
58 2. In all structs that include this interface, include the wrapping struct instead.  Functionally, this also fulfills the interface, so except for setting it or casting it to a sub-type it works the same.
59 3. Register the interface implementations as in the last init of common_test.go. If you are currently using go-wire, you should be doing this already
60
61 The benefits here is you can now run any of the following methods, both for
62 efficient storage in our go app, and a common format for rpc / humans.
63
64   orig := FooerS{foo}
65
66   // read/write binary a la tendermint/go-wire
67   bparsed := FooerS{}
68   err := wire.ReadBinaryBytes(
69     wire.BinaryBytes(orig), &bparsed)
70
71   // read/write json a la encoding/json
72   jparsed := FooerS{}
73   j, err := json.MarshalIndent(orig, "", "\t")
74   err = json.Unmarshal(j, &jparsed)
75
76 See https://github.com/tendermint/go-wire/data/blob/master/common_test.go to see
77 how to set up your code to use this.
78 */
79 package data