Merge pull request #224 from colincross/slice_of_structs

Allow mutated property structs to contain slices of non-strings
diff --git a/proptools/clone.go b/proptools/clone.go
index 9948b9a..dbd72b4 100644
--- a/proptools/clone.go
+++ b/proptools/clone.go
@@ -52,9 +52,6 @@
 			CopyProperties(dstFieldValue, srcFieldValue)
 		case reflect.Slice:
 			if !srcFieldValue.IsNil() {
-				if field.Type.Elem().Kind() != reflect.String {
-					panic(fmt.Errorf("can't copy field %q: slice elements are not strings", field.Name))
-				}
 				if srcFieldValue != dstFieldValue {
 					newSlice := reflect.MakeSlice(field.Type, srcFieldValue.Len(),
 						srcFieldValue.Len())
diff --git a/proptools/clone_test.go b/proptools/clone_test.go
index b6f1bf6..660f1c0 100644
--- a/proptools/clone_test.go
+++ b/proptools/clone_test.go
@@ -71,6 +71,19 @@
 		out: &struct{ S []string }{},
 	},
 	{
+		// Clone slice of structs
+		in: &struct{ S []struct{ T string } }{
+			S: []struct{ T string }{
+				{"string1"}, {"string2"},
+			},
+		},
+		out: &struct{ S []struct{ T string } }{
+			S: []struct{ T string }{
+				{"string1"}, {"string2"},
+			},
+		},
+	},
+	{
 		// Clone pointer to bool
 		in: &struct{ B1, B2 *bool }{
 			B1: BoolPtr(true),
@@ -317,6 +330,17 @@
 		out: &struct{ S []string }{},
 	},
 	{
+		// Clone slice of structs
+		in: &struct{ S []struct{ T string } }{
+			S: []struct{ T string }{
+				{"string1"}, {"string2"},
+			},
+		},
+		out: &struct{ S []struct{ T string } }{
+			S: []struct{ T string }(nil),
+		},
+	},
+	{
 		// Clone pointer to bool
 		in: &struct{ B1, B2 *bool }{
 			B1: BoolPtr(true),
diff --git a/unpack.go b/unpack.go
index cd165da..3156599 100644
--- a/unpack.go
+++ b/unpack.go
@@ -163,7 +163,9 @@
 		case reflect.Slice:
 			elemType := field.Type.Elem()
 			if elemType.Kind() != reflect.String {
-				panic(fmt.Errorf("field %s is a non-string slice", propertyName))
+				if !proptools.HasTag(field, "blueprint", "mutated") {
+					panic(fmt.Errorf("field %s is a non-string slice", propertyName))
+				}
 			}
 		case reflect.Interface:
 			if fieldValue.IsNil() {
diff --git a/unpack_test.go b/unpack_test.go
index b65fa3f..d6b88ab 100644
--- a/unpack_test.go
+++ b/unpack_test.go
@@ -111,13 +111,15 @@
 		`,
 		output: []interface{}{
 			struct {
-				Stuff []string
-				Empty []string
-				Nil   []string
+				Stuff     []string
+				Empty     []string
+				Nil       []string
+				NonString []struct{ S string } `blueprint:"mutated"`
 			}{
-				Stuff: []string{"asdf", "jkl;", "qwert", "uiop", "bnm,"},
-				Empty: []string{},
-				Nil:   nil,
+				Stuff:     []string{"asdf", "jkl;", "qwert", "uiop", "bnm,"},
+				Empty:     []string{},
+				Nil:       nil,
+				NonString: nil,
 			},
 		},
 	},