Skip to content

Commit

Permalink
Merge pull request #3 from kovetskiy/master
Browse files Browse the repository at this point in the history
add -init parameter
  • Loading branch information
kovetskiy authored Feb 25, 2020
2 parents 3aa32df + e377ae2 commit c15c70b
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 4 deletions.
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ also you can get the pre-built binaries on [Releases](https://github.com/moznion
Usage of gonstructor:
-constructorTypes string
[optional] comma-separated list of constructor types; it expects "allArgs" and "builder" (default "allArgs")
-init string
[optional] name of function to call on object after creating it
-output string
[optional] output file name (default "srcdir/<type>_gen.go")
-type string
Expand Down Expand Up @@ -107,6 +109,42 @@ func (b *StructureBuilder) Build() *Structure {
}
```

### Call a initializer

1. write a struct type with `go:generate`
2. write a function that initializes internal fields
3. pass its name to `-init` parameter

e.g.

```go
//go:generate gonstructor --type=Structure -init construct
type Structure struct {
foo string
bar io.Reader
Buz chan interface{}
bufferSize int
buffer chan []byte `gonstructor:"-"`
}

func (structure *Structure) construct() {
structure.buffer = make(chan []byte, structure.bufferSize)
}
```

2. execute `go generate ./...`
3. then `gonstructor` generates a buildr code

e.g.

```go
func NewStructure(foo string, bar io.Reader, buz chan interface{}, bufferSize int) *Structure {
r := &Structure{foo: foo, bar: bar, Buz: buz, bufferSize: bufferSize}
r.construct()
return r
}
```

## How to ignore to contain a field in a constructor

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

moznion (<moznion@gmail.com>)

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

func main() {
Expand Down Expand Up @@ -82,11 +83,13 @@ func main() {
constructorGenerator = &constructor.AllArgsConstructorGenerator{
TypeName: *typeName,
Fields: fields,
InitFunc: *initFunc,
}
case builderConstructorType:
constructorGenerator = &constructor.BuilderGenerator{
TypeName: *typeName,
Fields: fields,
InitFunc: *initFunc,
}
default:
// unreachable, just in case
Expand Down
21 changes: 19 additions & 2 deletions internal/constructor/all_args_constructor_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
type AllArgsConstructorGenerator struct {
TypeName string
Fields []*Field
InitFunc string
}

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

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

return g.NewFunc(
retStructure := fmt.Sprintf("&%s{%s}", cg.TypeName, strings.Join(retStructureKeyValues, ","))

var stmts []g.Statement
if cg.InitFunc != "" {
stmts = []g.Statement{
g.NewRawStatementf("r := %s", retStructure),
g.NewRawStatementf("r.%s()", cg.InitFunc),
g.NewReturnStatement("r"),
}
} else {
stmts = []g.Statement{
g.NewReturnStatement(retStructure),
}
}

fn := g.NewFunc(
nil,
funcSignature,
g.NewReturnStatement(fmt.Sprintf("&%s{%s}", cg.TypeName, strings.Join(retStructureKeyValues, ","))),
stmts...,
)
return fn
}
17 changes: 16 additions & 1 deletion internal/constructor/builder_constructor_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
type BuilderGenerator struct {
TypeName string
Fields []*Field
InitFunc string
}

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

buildResult := fmt.Sprintf("&%s{%s}", cg.TypeName, strings.Join(retStructureKeyValues, ","))

var buildStmts []g.Statement
if cg.InitFunc != "" {
buildStmts = append(buildStmts, g.NewRawStatementf("r := %s", buildResult))
buildStmts = append(buildStmts, g.NewRawStatementf("r.%s()", cg.InitFunc))
buildStmts = append(buildStmts, g.NewReturnStatement("r"))
} else {
buildStmts = append(
buildStmts,
g.NewReturnStatement(buildResult),
)
}

buildFunc := g.NewFunc(
g.NewFuncReceiver("b", "*"+builderType),
g.NewFuncSignature("Build").
AddReturnTypes("*"+cg.TypeName),
g.NewReturnStatement(fmt.Sprintf("&%s{%s}", cg.TypeName, strings.Join(retStructureKeyValues, ","))),
buildStmts...,
)

stmt := g.NewRoot(builderStruct, builderConstructorFunc)
Expand Down
11 changes: 11 additions & 0 deletions internal/test/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,14 @@ type ChildStructure struct {
structure *Structure
foobar string
}

//go:generate sh -c "$(cd ./\"$(git rev-parse --show-cdup)\" || exit; pwd)/dist/gonstructor_test --type=StructureWithInit --constructorTypes=allArgs,builder --withGetter --init initialize"
type StructureWithInit struct {
foo string
status string `gonstructor:"-"`
qux interface{} `gonstructor:"-"`
}

func (structure *StructureWithInit) initialize() {
structure.status = "ok"
}
29 changes: 29 additions & 0 deletions internal/test/structure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,32 @@ func TestChildStructureAllArgsConstructor(t *testing.T) {
assert.EqualValues(t, structure, got.structure)
assert.EqualValues(t, givenString, got.foobar)
}

func TestStructureWithInitAllArgsConstructor(t *testing.T) {
givenString := "givenstr"

got := NewStructureWithInit(givenString)
assert.IsType(t, &StructureWithInit{}, got)

assert.EqualValues(t, givenString, got.foo)
assert.EqualValues(t, "ok", got.status)
assert.EqualValues(t, nil, got.qux)

// test for getters
assert.EqualValues(t, givenString, got.GetFoo())
assert.EqualValues(t, "ok", got.GetStatus())
assert.EqualValues(t, nil, got.GetQux())
}

func TestStructureWithInitBuilder(t *testing.T) {
givenString := "givenstr"

b := NewStructureWithInitBuilder()
got := b.Foo(givenString).
Build()
assert.IsType(t, &StructureWithInit{}, got)

assert.EqualValues(t, givenString, got.foo)
assert.EqualValues(t, "ok", got.status)
assert.EqualValues(t, nil, got.qux)
}

0 comments on commit c15c70b

Please sign in to comment.