Skip to content

Commit

Permalink
✨ feat: structs - func InitDefaults() support set slice field
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Jan 28, 2023
1 parent f87fc86 commit 948fa70
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
24 changes: 18 additions & 6 deletions structs/setval.go
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/gookit/goutil/internal/comfunc"
"github.com/gookit/goutil/reflects"
"github.com/gookit/goutil/strutil"
)

const defaultInitTag = "default"
Expand All @@ -30,7 +31,7 @@ type InitOptions struct {
//
// TIPS:
//
// Only support init set: string, bool, intX, uintX, floatX
// Support init field types: string, bool, intX, uintX, floatX, array, slice
//
// Example:
//
Expand All @@ -41,8 +42,7 @@ type InitOptions struct {
//
// u1 := &User1{}
// err = structs.InitDefaults(u1)
// fmt.Printf("%+v\n", u1)
// // Output: {Name:inhere Age:30}
// fmt.Printf("%+v\n", u1) // Output: {Name:inhere Age:30}
func InitDefaults(ptr any, optFns ...InitOptFunc) error {
rv := reflect.ValueOf(ptr)
if rv.Kind() != reflect.Ptr {
Expand Down Expand Up @@ -85,8 +85,8 @@ func initDefaults(rv reflect.Value, opt *InitOptions) error {
continue
}

tagVal := ft.Tag.Get(opt.TagName)
if err := initDefaultValue(fv, tagVal, opt.ParseEnv); err != nil {
val := ft.Tag.Get(opt.TagName)
if err := initDefaultValue(fv, val, opt.ParseEnv); err != nil {
return err
}
}
Expand All @@ -104,8 +104,20 @@ func initDefaultValue(fv reflect.Value, val string, parseEnv bool) error {
val = comfunc.ParseEnvVar(val, nil)
}

var anyVal any = val

// convert string to slice
if reflects.IsArrayOrSlice(fv.Kind()) {
ss := strutil.SplitTrimmed(val, ",")
valRv, err := reflects.ConvSlice(reflect.ValueOf(ss), fv.Type().Elem())
if err != nil {
return err
}
anyVal = valRv.Interface()
}

// set value
return reflects.SetValue(fv, val)
return reflects.SetValue(fv, anyVal)
}

/*************************************************************
Expand Down
18 changes: 18 additions & 0 deletions structs/setval_test.go
Expand Up @@ -47,6 +47,24 @@ func TestInitDefaults(t *testing.T) {
assert.ErrMsg(t, err, "must be provider an struct value")
}

func TestInitDefaults_sliceField(t *testing.T) {
type InitSliceFld struct {
Name string `default:"inhere"`
Age int `default:""`
Tags []string `default:"php,go"`
TagIds []int64 `default:"34,456"`
}

u := &InitSliceFld{}
err := structs.InitDefaults(u)
dump.P(u)

assert.NoErr(t, err)
assert.Eq(t, "inhere", u.Name)
assert.Eq(t, []string{"php", "go"}, u.Tags)
assert.Eq(t, []int64{34, 456}, u.TagIds)
}

func TestInitDefaults_parseEnv(t *testing.T) {
type App struct {
Name string `default:"${ APP_NAME | my-app }"`
Expand Down

0 comments on commit 948fa70

Please sign in to comment.