Skip to content

Commit

Permalink
feat: support schema field name customization (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
nrwiersma authored Sep 12, 2024
1 parent b109997 commit 47bc101
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
16 changes: 15 additions & 1 deletion schemagen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,26 @@ type DocsFunc = func(obj any, sf reflect.StructField) string
// if the field should be skipped.
type CustomizerFunc = func(obj any, sf *reflect.StructField, typ reflect.Type, s *schema.Schema) (string, reflect.Kind, bool)

// NameFunc is a function used to determine a field name.
type NameFunc = func(name string) string

var errSkip = errors.New("skip")

// Generator generates Terraform schemas.
type Generator struct {
docsFn DocsFunc
customizerFn CustomizerFunc
tag string
nameFn NameFunc
}

// New returns a schema generator.
func New(docsFn DocsFunc, customizerFn CustomizerFunc, tag string) *Generator {
return NewWithName(docsFn, customizerFn, nil, tag)
}

// NewWithName returns a schema generator with the given nameFn.
func NewWithName(docsFn DocsFunc, customizerFn CustomizerFunc, nameFn NameFunc, tag string) *Generator {
if tag == "" {
tag = "json"
}
Expand All @@ -45,10 +54,14 @@ func New(docsFn DocsFunc, customizerFn CustomizerFunc, tag string) *Generator {
return "", typ.Kind(), true
}
}
if nameFn == nil {
nameFn = strcase.ToSnake
}

return &Generator{
docsFn: docsFn,
customizerFn: customizerFn,
nameFn: nameFn,
tag: tag,
}
}
Expand Down Expand Up @@ -78,7 +91,8 @@ func (g *Generator) Struct(obj any) (map[string]string, error) {
}
}

fields[strcase.ToSnake(name)] = code
fieldName := g.nameFn(name)
fields[fieldName] = code
}
return fields, nil
}
Expand Down
25 changes: 25 additions & 0 deletions schemagen/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"reflect"
"testing"

"github.com/ettle/strcase"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/nitrado/tfconv/schemagen"
"github.com/stretchr/testify/assert"
Expand All @@ -29,6 +30,30 @@ func TestGenerator_Struct(t *testing.T) {
assert.Equal(t, want, got)
}

func TestGenerator_StructWithName(t *testing.T) {
gen := schemagen.NewWithName(nil, nil, func(name string) string {
if name == "float" {
return "other"
}
return strcase.ToSnake(name)
}, "")

got, err := gen.Struct(&TestObject{})

require.NoError(t, err)
want := map[string]string{
"other": "{\nType: schema.TypeFloat,\n}",
"int": "{\nType: schema.TypeInt,\n}",
"str": "{\nType: schema.TypeString,\n}",
"bool": "{\nType: schema.TypeBool,\n}",
"ptr_bool": "{\nType: schema.TypeList,\nMaxItems: 1,\nElem: &schema.Resource{\nSchema: map[string]*schema.Schema{\n\"value\": {\nType: schema.TypeBool,\nRequired: true,\n},\n},\n},\n}",
"slice": "{\nType: schema.TypeList,\nElem: &schema.Resource{\nSchema: map[string]*schema.Schema{\n\"a\": {\nType: schema.TypeString,\n},\n},\n},\n}",
"map": "{\nType: schema.TypeMap,\nElem: &schema.Schema{Type: schema.TypeInt,},\n}",
"struct": "{\nType: schema.TypeList,\nMaxItems: 1,\nElem: &schema.Resource{\nSchema: map[string]*schema.Schema{\n\"a\": {\nType: schema.TypeString,\n},\n},\n},\n}",
}
assert.Equal(t, want, got)
}

func TestGenerator_StructUsesCustomFunction(t *testing.T) {
c := func(_ any, _ *reflect.StructField, typ reflect.Type, _ *schema.Schema) (string, reflect.Kind, bool) {
if typ == reflect.TypeOf(T{}) {
Expand Down

0 comments on commit 47bc101

Please sign in to comment.