diff options
| author | Maciej Borzecki <maciej.zenon.borzecki@canonical.com> | 2019-04-01 16:06:36 +0200 |
|---|---|---|
| committer | Maciej Borzecki <maciej.zenon.borzecki@canonical.com> | 2019-04-01 16:13:46 +0200 |
| commit | 4022cc7d32cc4e9fd7cd81c9fd95a8ed843e25f1 (patch) | |
| tree | bbcd71435d1eaa6c17f9dca99f8241b1ced34915 /metautil | |
| parent | 360bb174256ff915a9ccc6680519ea88e758e09a (diff) | |
metautil, snap: extract yaml value normalization to a helper package
The value normalization bits will be reused by the 'gadget' package. Extract the code into a separate helper package. Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Diffstat (limited to 'metautil')
| -rw-r--r-- | metautil/normalize.go | 79 | ||||
| -rw-r--r-- | metautil/normalize_test.go | 71 |
2 files changed, 150 insertions, 0 deletions
diff --git a/metautil/normalize.go b/metautil/normalize.go new file mode 100644 index 0000000000..c6f8d0e824 --- /dev/null +++ b/metautil/normalize.go @@ -0,0 +1,79 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2016 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package metautil + +import ( + "fmt" +) + +// NormalizeValue validates values and returns a normalized version of it +// (map[interface{}]interface{} is turned into map[string]interface{}) +func NormalizeValue(v interface{}) (interface{}, error) { + switch x := v.(type) { + case string: + return x, nil + case bool: + return x, nil + case int: + return int64(x), nil + case int64: + return x, nil + case float64: + return x, nil + case float32: + return float64(x), nil + case []interface{}: + l := make([]interface{}, len(x)) + for i, el := range x { + el, err := NormalizeValue(el) + if err != nil { + return nil, err + } + l[i] = el + } + return l, nil + case map[interface{}]interface{}: + m := make(map[string]interface{}, len(x)) + for k, item := range x { + kStr, ok := k.(string) + if !ok { + return nil, fmt.Errorf("non-string key: %v", k) + } + item, err := NormalizeValue(item) + if err != nil { + return nil, err + } + m[kStr] = item + } + return m, nil + case map[string]interface{}: + m := make(map[string]interface{}, len(x)) + for k, item := range x { + item, err := NormalizeValue(item) + if err != nil { + return nil, err + } + m[k] = item + } + return m, nil + default: + return nil, fmt.Errorf("invalid scalar: %v", v) + } +} diff --git a/metautil/normalize_test.go b/metautil/normalize_test.go new file mode 100644 index 0000000000..7e29e1db18 --- /dev/null +++ b/metautil/normalize_test.go @@ -0,0 +1,71 @@ +// -*- Mode: Go; indent-tabs-mode: t -*- + +/* + * Copyright (C) 2014-2016 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package metautil_test + +import ( + "testing" + + . "gopkg.in/check.v1" + + "github.com/snapcore/snapd/metautil" +) + +type normalizeTestSuite struct { +} + +var _ = Suite(&normalizeTestSuite{}) + +func TestMain(t *testing.T) { TestingT(t) } + +func (s *normalizeTestSuite) TestNormalize(c *C) { + for _, tc := range []struct { + v interface{} + exp interface{} + err string + }{ + {v: "foo", exp: "foo"}, + {v: 1, exp: int64(1)}, + {v: int64(1), exp: int64(1)}, + {v: true, exp: true}, + {v: 0.5, exp: float64(0.5)}, + {v: float32(0.5), exp: float64(0.5)}, + {v: float64(0.5), exp: float64(0.5)}, + {v: []interface{}{1, 0.5, "foo"}, exp: []interface{}{int64(1), float64(0.5), "foo"}}, + {v: map[string]interface{}{"foo": 1}, exp: map[string]interface{}{"foo": int64(1)}}, + {v: map[interface{}]interface{}{"foo": 1}, exp: map[string]interface{}{"foo": int64(1)}}, + { + v: map[interface{}]interface{}{"foo": map[interface{}]interface{}{"bar": 0.5}}, + exp: map[string]interface{}{"foo": map[string]interface{}{"bar": float64(0.5)}}, + }, + {v: uint(1), err: "invalid scalar: 1"}, + {v: map[interface{}]interface{}{2: 1}, err: "non-string key: 2"}, + {v: []interface{}{uint(1)}, err: "invalid scalar: 1"}, + {v: map[string]interface{}{"foo": uint(1)}, err: "invalid scalar: 1"}, + {v: map[interface{}]interface{}{"foo": uint(1)}, err: "invalid scalar: 1"}, + } { + res, err := metautil.NormalizeValue(tc.v) + if tc.err == "" { + c.Assert(err, IsNil) + c.Assert(res, DeepEquals, tc.exp) + } else { + c.Assert(err, ErrorMatches, tc.err) + } + } +} |
