Skip to content

Commit

Permalink
added a basic tag builder as a compiler-friendly alternative to speci…
Browse files Browse the repository at this point in the history
…fying tags in annotations
  • Loading branch information
johnabass committed Jun 16, 2023
1 parent d30748c commit 273e371
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
73 changes: 73 additions & 0 deletions tagBuilder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package arrange

import (
"reflect"
"strings"

"go.uber.org/fx"
)

type TagBuilder struct {
tags []string
}

func (tb *TagBuilder) Skip() *TagBuilder {
tb.tags = append(tb.tags, "")
return tb
}

func (tb *TagBuilder) Optional() *TagBuilder {
tb.tags = append(tb.tags, `optional:"true"`)
return tb
}

func (tb *TagBuilder) Name(v string) *TagBuilder {
var o strings.Builder
o.WriteString(`name:"`)
o.WriteString(v)
o.WriteRune('"')
tb.tags = append(tb.tags, o.String())

return tb
}

func (tb *TagBuilder) OptionalName(v string) *TagBuilder {
var o strings.Builder
o.WriteString(`name:"`)
o.WriteString(v)
o.WriteString(`" optional:"true"`)
tb.tags = append(tb.tags, o.String())

return tb
}

func (tb *TagBuilder) Group(v string) *TagBuilder {
var o strings.Builder
o.WriteString(`group:"`)
o.WriteString(v)
o.WriteRune('"')
tb.tags = append(tb.tags, o.String())

return tb
}

func (tb *TagBuilder) StructTags() (tags []reflect.StructTag) {
tags = make([]reflect.StructTag, 0, len(tb.tags))
for _, v := range tb.tags {
tags = append(tags, reflect.StructTag(v))
}

return
}

func (tb *TagBuilder) ParamTags() fx.Annotation {
return fx.ParamTags(tb.tags...)
}

func (tb *TagBuilder) ResultTags() fx.Annotation {
return fx.ResultTags(tb.tags...)
}

func Tags() *TagBuilder {
return new(TagBuilder)
}
57 changes: 57 additions & 0 deletions tagBuilder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package arrange

import (
"bytes"
"testing"

"github.com/stretchr/testify/suite"
"go.uber.org/fx"
"go.uber.org/fx/fxtest"
)

type TagBuilderSuite struct {
suite.Suite
}

func (suite *TagBuilderSuite) TestParamTags() {
type parameters struct {
fx.Out

Named string `name:"name"`
Values []string `group:"values"`
}

var buffer *bytes.Buffer
app := fxtest.New(
suite.T(),
fx.Provide(
func() parameters {
return parameters{} // doesn't matter what the values are
},
func() int { return 123 },
fx.Annotate(
func(
name string, optional string, values []string, optionalUnnamed string, skipped int,
) *bytes.Buffer {
return new(bytes.Buffer) // dummy component
},
Tags().
Name("name").
OptionalName("optional").
Group("values").
Optional().
Skip().
ParamTags(),
),
),
fx.Populate(&buffer), // force the constructor to run
)

app.RequireStart()
app.RequireStop()
suite.NotNil(buffer)
}

func TestTagBuilder(t *testing.T) {
suite.Run(t, new(TagBuilderSuite))
}

0 comments on commit 273e371

Please sign in to comment.