OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / go-wire / gen / README.md
1 # Codegen for Interface Wrappers
2
3 We often want to wrap interfaces in structs to help with wire and json serialization.  However, there is a lot of boilerplate, so I made this tool.  Look at `go-crypto/pubkeyinner_holder.go` for an example of the boilerplate ...
4
5 ## Setup (one-time)
6
7 Before you can run the codegen, you need to install the proper tooling on your system. Just go to the most recent `develop` of `go-wire` and type:
8
9 ```bash
10 make tools
11 ```
12
13 ## Testing it out...
14
15 Let's see if this works now... go to `go-crypto` and checkout `data-codegen` (if it has not yet been merged into `develop`).  Now, to prepare and execute the generator, type:
16
17 ```bash
18 make prepgen
19 make codegen
20 ```
21
22 If you see no errors, it works!  You can verify by adding some random comments in `pubkeyinner_holder.go` and running `make codegen` again.  It will re-generate the code and they will disappear.
23
24 ## Adding it to your repo
25
26 The best time to use it is when you create the interface... otherwise it is a bit of a dance to port code without causing duplicate names and uncompilable code.  If this is you, talk to Frey.  But best to use this when you start writing all the interfaces.
27
28 First, go to the directory that has the interface you want to wrap, and create the following file as `_gen.go`:
29
30 ```Go
31 package main
32
33 import (
34   _ "github.com/tendermint/go-wire/gen"
35 )
36 ```
37
38 Now, go to the interface you want to wrap and place a comment before it.  Like:
39
40 ```Go
41 // +gen holder:"Food,Impl[Bling,*Fuzz]"
42 type FooInner interface {
43   Bar() int
44 }
45 ```
46
47 Let's disect what this line means...
48
49 ```Go
50 // +gen holder:"STRUCT_NAME,Impl[IMPLEMENATION_STRUCTS...],(JSON_NAMES,...)"
51 ```
52
53 If you run it with nothing, just `// +gen holder`, it will create a surrounding struct with the name `FooInnerHolder` and register no implementations. This is rarely desired.
54
55 If you just add a name, it will apply the name to the surrounding struct.  So `// +gen holder:"Food"` leads to...
56
57 ```Go
58 type Food Struct {
59   FooInner `json:"unwrap"`
60 }
61 ```
62
63 It provides all the helper methods, which is great, but you still have to register the implementations.  If you want to use codegen for this, then add a tag called `Impl[]` and include the class names inside the brackets.  Prepend `*` if the pointer receiver is what fulfills the interface, so we generate the proper bindings. This will add a `Wrap()` method to those implementations and register them with go-wire (and data) for easy serialization and deserialization.
64
65 ## Running it in your repo
66
67 This will run code from `github.com/tendermin/go-wire/gen` to do the actual codegen, and knowing go, it will look in your vendor directory if you have one... so update glide and make sure you have a recent version of `go-wire:develop` in your vendor dir.
68
69 Then... just type `gen` in the same directory... suddenly a brand new file will appear called `fooinner_holder.go` or whatever the interface name was that we wrapped.
70
71 Enjoy!
72
73 One nice bonus, is if we add methods to the codegen templates, you just have to update go-wire in your vendor dir and re-run `gen` to get the new code.