Skip to content

Commit c15c70b

Browse files
authored
Merge pull request #3 from kovetskiy/master
add -init parameter
2 parents 3aa32df + e377ae2 commit c15c70b

File tree

6 files changed

+116
-4
lines changed

6 files changed

+116
-4
lines changed

README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ also you can get the pre-built binaries on [Releases](https://github.com/moznion
1616
Usage of gonstructor:
1717
-constructorTypes string
1818
[optional] comma-separated list of constructor types; it expects "allArgs" and "builder" (default "allArgs")
19+
-init string
20+
[optional] name of function to call on object after creating it
1921
-output string
2022
[optional] output file name (default "srcdir/<type>_gen.go")
2123
-type string
@@ -107,6 +109,42 @@ func (b *StructureBuilder) Build() *Structure {
107109
}
108110
```
109111

112+
### Call a initializer
113+
114+
1. write a struct type with `go:generate`
115+
2. write a function that initializes internal fields
116+
3. pass its name to `-init` parameter
117+
118+
e.g.
119+
120+
```go
121+
//go:generate gonstructor --type=Structure -init construct
122+
type Structure struct {
123+
foo string
124+
bar io.Reader
125+
Buz chan interface{}
126+
bufferSize int
127+
buffer chan []byte `gonstructor:"-"`
128+
}
129+
130+
func (structure *Structure) construct() {
131+
structure.buffer = make(chan []byte, structure.bufferSize)
132+
}
133+
```
134+
135+
2. execute `go generate ./...`
136+
3. then `gonstructor` generates a buildr code
137+
138+
e.g.
139+
140+
```go
141+
func NewStructure(foo string, bar io.Reader, buz chan interface{}, bufferSize int) *Structure {
142+
r := &Structure{foo: foo, bar: bar, Buz: buz, bufferSize: bufferSize}
143+
r.construct()
144+
return r
145+
}
146+
```
147+
110148
## How to ignore to contain a field in a constructor
111149

112150
`gonstructor:"-"` supports that.
@@ -129,4 +167,3 @@ Binaries are built and uploaded by [goreleaser](https://goreleaser.com/). Please
129167
## Author
130168

131169
moznion (<moznion@gmail.com>)
132-

cmd/gonstructor/gonstructor.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ var (
2626
constructorTypes = flag.String("constructorTypes", allArgsConstructorType, fmt.Sprintf(`[optional] comma-separated list of constructor types; it expects "%s" and "%s"`, allArgsConstructorType, builderConstructorType))
2727
shouldShowVersion = flag.Bool("version", false, "[optional] show the version information")
2828
withGetter = flag.Bool("withGetter", false, "[optional] generate a constructor along with getter functions for each field")
29+
initFunc = flag.String("init", "", "[optional] name of function to call on object after creating it")
2930
)
3031

3132
func main() {
@@ -82,11 +83,13 @@ func main() {
8283
constructorGenerator = &constructor.AllArgsConstructorGenerator{
8384
TypeName: *typeName,
8485
Fields: fields,
86+
InitFunc: *initFunc,
8587
}
8688
case builderConstructorType:
8789
constructorGenerator = &constructor.BuilderGenerator{
8890
TypeName: *typeName,
8991
Fields: fields,
92+
InitFunc: *initFunc,
9093
}
9194
default:
9295
// unreachable, just in case

internal/constructor/all_args_constructor_generator.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
type AllArgsConstructorGenerator struct {
1313
TypeName string
1414
Fields []*Field
15+
InitFunc string
1516
}
1617

1718
// Generate generates a constructor statement with all of arguments.
@@ -29,9 +30,25 @@ func (cg *AllArgsConstructorGenerator) Generate() g.Statement {
2930

3031
funcSignature = funcSignature.AddReturnTypes("*" + cg.TypeName)
3132

32-
return g.NewFunc(
33+
retStructure := fmt.Sprintf("&%s{%s}", cg.TypeName, strings.Join(retStructureKeyValues, ","))
34+
35+
var stmts []g.Statement
36+
if cg.InitFunc != "" {
37+
stmts = []g.Statement{
38+
g.NewRawStatementf("r := %s", retStructure),
39+
g.NewRawStatementf("r.%s()", cg.InitFunc),
40+
g.NewReturnStatement("r"),
41+
}
42+
} else {
43+
stmts = []g.Statement{
44+
g.NewReturnStatement(retStructure),
45+
}
46+
}
47+
48+
fn := g.NewFunc(
3349
nil,
3450
funcSignature,
35-
g.NewReturnStatement(fmt.Sprintf("&%s{%s}", cg.TypeName, strings.Join(retStructureKeyValues, ","))),
51+
stmts...,
3652
)
53+
return fn
3754
}

internal/constructor/builder_constructor_generator.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
type BuilderGenerator struct {
1313
TypeName string
1414
Fields []*Field
15+
InitFunc string
1516
}
1617

1718
// Generate generates a builder statement.
@@ -51,11 +52,25 @@ func (cg *BuilderGenerator) Generate() g.Statement {
5152
retStructureKeyValues = append(retStructureKeyValues, fmt.Sprintf("%s: b.%s", field.FieldName, toLowerCamel(field.FieldName)))
5253
}
5354

55+
buildResult := fmt.Sprintf("&%s{%s}", cg.TypeName, strings.Join(retStructureKeyValues, ","))
56+
57+
var buildStmts []g.Statement
58+
if cg.InitFunc != "" {
59+
buildStmts = append(buildStmts, g.NewRawStatementf("r := %s", buildResult))
60+
buildStmts = append(buildStmts, g.NewRawStatementf("r.%s()", cg.InitFunc))
61+
buildStmts = append(buildStmts, g.NewReturnStatement("r"))
62+
} else {
63+
buildStmts = append(
64+
buildStmts,
65+
g.NewReturnStatement(buildResult),
66+
)
67+
}
68+
5469
buildFunc := g.NewFunc(
5570
g.NewFuncReceiver("b", "*"+builderType),
5671
g.NewFuncSignature("Build").
5772
AddReturnTypes("*"+cg.TypeName),
58-
g.NewReturnStatement(fmt.Sprintf("&%s{%s}", cg.TypeName, strings.Join(retStructureKeyValues, ","))),
73+
buildStmts...,
5974
)
6075

6176
stmt := g.NewRoot(builderStruct, builderConstructorFunc)

internal/test/structure.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,14 @@ type ChildStructure struct {
1515
structure *Structure
1616
foobar string
1717
}
18+
19+
//go:generate sh -c "$(cd ./\"$(git rev-parse --show-cdup)\" || exit; pwd)/dist/gonstructor_test --type=StructureWithInit --constructorTypes=allArgs,builder --withGetter --init initialize"
20+
type StructureWithInit struct {
21+
foo string
22+
status string `gonstructor:"-"`
23+
qux interface{} `gonstructor:"-"`
24+
}
25+
26+
func (structure *StructureWithInit) initialize() {
27+
structure.status = "ok"
28+
}

internal/test/structure_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,32 @@ func TestChildStructureAllArgsConstructor(t *testing.T) {
5555
assert.EqualValues(t, structure, got.structure)
5656
assert.EqualValues(t, givenString, got.foobar)
5757
}
58+
59+
func TestStructureWithInitAllArgsConstructor(t *testing.T) {
60+
givenString := "givenstr"
61+
62+
got := NewStructureWithInit(givenString)
63+
assert.IsType(t, &StructureWithInit{}, got)
64+
65+
assert.EqualValues(t, givenString, got.foo)
66+
assert.EqualValues(t, "ok", got.status)
67+
assert.EqualValues(t, nil, got.qux)
68+
69+
// test for getters
70+
assert.EqualValues(t, givenString, got.GetFoo())
71+
assert.EqualValues(t, "ok", got.GetStatus())
72+
assert.EqualValues(t, nil, got.GetQux())
73+
}
74+
75+
func TestStructureWithInitBuilder(t *testing.T) {
76+
givenString := "givenstr"
77+
78+
b := NewStructureWithInitBuilder()
79+
got := b.Foo(givenString).
80+
Build()
81+
assert.IsType(t, &StructureWithInit{}, got)
82+
83+
assert.EqualValues(t, givenString, got.foo)
84+
assert.EqualValues(t, "ok", got.status)
85+
assert.EqualValues(t, nil, got.qux)
86+
}

0 commit comments

Comments
 (0)