diff --git a/field.go b/field.go index 8eec45a..507ed4e 100644 --- a/field.go +++ b/field.go @@ -59,12 +59,6 @@ func fieldFromType(name string, t reflect.Type) Field { func prependFieldName(name string, f []Field) { for i := range f { - if f[i].name == "" { - f[i].name = strcase.ToKebab(name) - f[i].path = []string{name} - continue - } - f[i].name = fmt.Sprintf("%s-%s", strcase.ToKebab(name), f[i].name) f[i].path = append([]string{name}, f[i].path...) } @@ -160,7 +154,16 @@ func structFields(v reflect.Value) []Field { continue } - ffi := fieldValues(vi) + vvi := vi + if unpackType(fi.Type, pointer).Kind() == reflect.Slice { + var ok bool + vvi, ok = allocate(fi.Type, 1) + if !ok { + continue + } + } + + ffi := fieldValues(vvi) if !fi.Anonymous { prependFieldName(fi.Name, ffi) } @@ -278,11 +281,7 @@ func bindMapField(receiver reflect.Value, values []Field) bool { t := receiver.Type() kt := t.Key() vt := t.Elem() - kv, ok := bindScalarCreate(kt, []any{key}) - if !ok { - return false - } - + kv, _ := bindScalarCreate(kt, []any{key}) vv, ok := bindScalarCreate(vt, v) if !ok { return false @@ -370,10 +369,6 @@ func bindStructField(receiver reflect.Value, values []Field) bool { } func bindField(receiver reflect.Value, values []Field) bool { - if !receiver.IsValid() { - return false - } - if values[0].name == "" && len(values[0].path) == 0 { ret := bindScalarField(receiver, values) return ret diff --git a/field_test.go b/field_test.go index f2b92b9..1252b4d 100644 --- a/field_test.go +++ b/field_test.go @@ -128,6 +128,14 @@ func TestField(t *testing.T) { t.Fatal(notation.Sprint(f)) } }) + + t.Run("list of struct", func(t *testing.T) { + type s struct{Foo []struct{Bar int}} + f := bind.Fields[s]() + if len(f) != 1 || f[0].Name() != "foo-bar" || !f[0].List() { + t.Fatal() + } + }) }) t.Run("field values", func(t *testing.T) { @@ -358,6 +366,22 @@ func TestField(t *testing.T) { t.Fatal(notation.Sprint(f)) } }) + + t.Run("list of struct", func(t *testing.T) { + type s struct{Foo []struct{Bar int}} + var v s + f := bind.FieldValues(v) + if len(f) != 1 || f[0].Name() != "foo-bar" || !f[0].List() { + t.Fatal(notation.Sprint(f)) + } + }) + + t.Run("nil", func(t *testing.T) { + f := bind.FieldValues(nil) + if len(f) != 0 { + t.Fatal() + } + }) }) t.Run("bind fields", func(t *testing.T) { @@ -711,6 +735,19 @@ func TestField(t *testing.T) { } }) + t.Run("pointer field with invalid value", func(t *testing.T) { + type s struct {Foo *struct{ Bar int }} + var v s + u := bind.BindFields( + &v, + bind.NamedValue("foo-bar", "baz"), + ) + + if len(u) != 1 { + t.Fatal() + } + }) + t.Run("unsupported pointer fields", func(t *testing.T) { type s struct { Foo *int @@ -823,6 +860,14 @@ func TestField(t *testing.T) { t.Fatal(notation.Sprint(u), notation.Sprint(v)) } }) + + t.Run("scalar map with invalid field type", func(t *testing.T) { + v := make(map[string]int) + u := bind.BindFields(v, bind.NamedValue("foo", "bar")) + if len(u) != 1 { + t.Fatal() + } + }) }) t.Run("bind fields create", func(t *testing.T) {