From 1410239899d044882efcba0f976bf7bb8a00fc27 Mon Sep 17 00:00:00 2001 From: Jeremy Rickard Date: Thu, 20 Jun 2019 13:32:26 -0600 Subject: [PATCH] Reintroduce ConvertValue(interface{}) (#41) * Reintroduce ConvertValue(interface{}) This PR re-introduces the ConvertValue(interface{}) method, but relocates it to the definitions package. * Updated ConvertValue * Fix lint issues --- bundle/definition/schema.go | 33 ++++++++++++++++ bundle/definition/schema_test.go | 66 ++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/bundle/definition/schema.go b/bundle/definition/schema.go index 690a31c2..4a24436b 100644 --- a/bundle/definition/schema.go +++ b/bundle/definition/schema.go @@ -2,6 +2,8 @@ package definition import ( "encoding/json" + "strconv" + "strings" "github.com/pkg/errors" "github.com/qri-io/jsonschema" @@ -107,3 +109,34 @@ func (s *Schema) UnmarshalJSON(data []byte) error { } return json.Unmarshal(data, &wrapper) } + +// ConvertValue attempts to convert the given string value to the type from the +// definition. Note: this is only applicable to string, number, integer and boolean types +func (s *Schema) ConvertValue(val string) (interface{}, error) { + dataType, ok, err := s.GetType() + if !ok { + return nil, errors.Wrapf(err, "unable to determine type: %v", s.Type) + } + switch dataType { + case "string": + return val, nil + case "number": + num, err := strconv.ParseFloat(val, 64) + if err != nil { + return nil, errors.Wrapf(err, "unable to convert %s to number", val) + } + return num, nil + case "integer": + return strconv.Atoi(val) + case "boolean": + if strings.ToLower(val) == "true" { + return true, nil + } else if strings.ToLower(val) == "false" { + return false, nil + } else { + return false, errors.Errorf("%q is not a valid boolean", val) + } + default: + return nil, errors.New("invalid definition") + } +} diff --git a/bundle/definition/schema_test.go b/bundle/definition/schema_test.go index e54166a9..05a15a8d 100644 --- a/bundle/definition/schema_test.go +++ b/bundle/definition/schema_test.go @@ -269,3 +269,69 @@ func valueTestJSON(kind, def, enum string) []byte { "enum": [ %s ] }`, kind, def, enum)) } + +func TestConvertValue(t *testing.T) { + pd := Schema{ + Type: "boolean", + } + is := assert.New(t) + + out, _ := pd.ConvertValue("true") + is.True(out.(bool)) + out, _ = pd.ConvertValue("false") + is.False(out.(bool)) + out, _ = pd.ConvertValue("barbeque") + is.False(out.(bool)) + + pd.Type = "string" + out, err := pd.ConvertValue("hello") + is.NoError(err) + is.Equal("hello", out.(string)) + + pd.Type = "integer" + out, err = pd.ConvertValue("123") + is.NoError(err) + is.Equal(123, out.(int)) + + _, err = pd.ConvertValue("onetwothree") + is.Error(err) + + pd.Type = "number" + out, err = pd.ConvertValue("123") + is.NoError(err) + is.Equal(float64(123), out.(float64)) + + out, err = pd.ConvertValue("5.5") + is.NoError(err) + is.Equal(5.5, out.(float64)) + + _, err = pd.ConvertValue("nope") + is.Error(err) + + pd.Type = "array" + _, err = pd.ConvertValue("nope") + is.Error(err) + + _, err = pd.ConvertValue("123") + is.Error(err) + + _, err = pd.ConvertValue("true") + is.Error(err) + + _, err = pd.ConvertValue("123.5") + is.Error(err) + + pd.Type = "object" + _, err = pd.ConvertValue("nope") + is.Error(err) + + _, err = pd.ConvertValue("123") + is.Error(err) + + _, err = pd.ConvertValue("true") + is.Error(err) + + _, err = pd.ConvertValue("123.5") + is.Error(err) + +}