Issue #17: Add support for typed setters

This patch provides a generic SetValue() method
which accepts the value as interface{} and then
stores the default representation as defined by
fmt.Sprintf("%v") as value.
diff --git a/properties.go b/properties.go
index 80360c9..fb57f71 100644
--- a/properties.go
+++ b/properties.go
@@ -542,6 +542,13 @@
 	return prev, ok, nil
 }
 
+// SetValue sets property key to the default string value
+// as defined by fmt.Sprintf("%v").
+func (p *Properties) SetValue(key string, value interface{}) error {
+	_, _, err := p.Set(key, fmt.Sprintf("%v", value))
+	return err
+}
+
 // MustSet sets the property key to the corresponding value.
 // If a value for key existed before then ok is true and prev
 // contains the previous value. An empty key is silently ignored.
diff --git a/properties_test.go b/properties_test.go
index a63a560..df3d45b 100644
--- a/properties_test.go
+++ b/properties_test.go
@@ -719,6 +719,23 @@
 	}
 }
 
+func TestSetValue(t *testing.T) {
+	tests := []interface{}{
+		true, false,
+		int8(123), int16(123), int32(123), int64(123), int(123),
+		uint8(123), uint16(123), uint32(123), uint64(123), uint(123),
+		float32(1.23), float64(1.23),
+		"abc",
+	}
+
+	for _, v := range tests {
+		p := NewProperties()
+		err := p.SetValue("x", v)
+		assert.Equal(t, err, nil)
+		assert.Equal(t, p.GetString("x", ""), fmt.Sprintf("%v", v))
+	}
+}
+
 func TestMustSet(t *testing.T) {
 	input := "key=${key}"
 	p := mustParse(t, input)