Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #79 from coryb/master
Browse files Browse the repository at this point in the history
need to allow for custom types in struct with `survey:"..."` tags
  • Loading branch information
AlecAivazis authored Jul 19, 2017
2 parents 5c625c6 + 29c38da commit 2ad8367
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
23 changes: 17 additions & 6 deletions core/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ type fieldsettable interface {
WriteAnswerField(field string, value interface{}) error
}

func WriteAnswer(t interface{}, name string, v interface{}) (err error) {

func writeByInterfaces(t interface{}, name string, v interface{}) (handled bool, err error) {
if s, ok := t.(settable); ok {
return s.WriteAnswer(v)
return true, s.WriteAnswer(v)
}
if fs, ok := t.(fieldsettable); ok {
return fs.WriteAnswerField(name, v)
return true, fs.WriteAnswerField(name, v)
}
return false, nil
}

func WriteAnswer(t interface{}, name string, v interface{}) (err error) {
if handled, err := writeByInterfaces(t, name, v); handled {
return err
}

// the target to write to
Expand All @@ -52,9 +58,14 @@ func WriteAnswer(t interface{}, name string, v interface{}) (err error) {
// bubble up
return err
}

field := elem.Field(fieldIndex)
if field.CanAddr() {
if handled, err := writeByInterfaces(field.Addr().Interface(), name, v); handled {
return err
}
}
// copy the value over to the field
return copy(elem.Field(fieldIndex), value)
return copy(field, value)
case reflect.Map:
mapType := reflect.TypeOf(t).Elem()
if mapType.Key().Kind() != reflect.String || mapType.Elem().Kind() != reflect.Interface {
Expand Down
11 changes: 10 additions & 1 deletion core/write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ type testSettable struct {
Value string
}

type testSettableStruct struct {
Settable testSettable `survey:"settable"`
}

func (t *testSettable) WriteAnswer(value interface{}) error {
if v, ok := value.(string); ok {
t.Value = v
Expand All @@ -274,6 +278,11 @@ func TestWriteWithSettable(t *testing.T) {
err = WriteAnswer(&testSet2, "prompt", 123)
assert.Error(t, fmt.Errorf("Incompatible type int64"), err)
assert.Equal(t, "", testSet2.Value)

testSetStruct := testSettableStruct{}
err = WriteAnswer(&testSetStruct, "settable", "stringVal1")
assert.Nil(t, err)
assert.Equal(t, testSetStruct.Settable.Value, "stringVal1")
}

type testFieldSettable struct {
Expand Down Expand Up @@ -302,7 +311,7 @@ func TestWriteWithFieldSettable(t *testing.T) {
assert.Error(t, fmt.Errorf("Incompatible type int64"), err)
assert.Equal(t, map[string]string{}, testSet2.Values)
}

// CONVERSION TESTS
func TestWrite_canStringToBool(t *testing.T) {
// a pointer to hold the boolean value
Expand Down

0 comments on commit 2ad8367

Please sign in to comment.