Add UnmarshalStrict returning error if yaml has fields that do not exist in structure

This commit is contained in:
Witold Krecicki 2017-06-13 12:23:14 +02:00
Родитель cd8b52f826
Коммит f8db564a0a
3 изменённых файлов: 28 добавлений и 3 удалений

Просмотреть файл

@ -190,6 +190,7 @@ type decoder struct {
aliases map[string]bool
mapType reflect.Type
terrors []string
strict bool
}
var (
@ -199,8 +200,8 @@ var (
ifaceType = defaultMapType.Elem()
)
func newDecoder() *decoder {
d := &decoder{mapType: defaultMapType}
func newDecoder(strict bool) *decoder {
d := &decoder{mapType: defaultMapType, strict: strict}
d.aliases = make(map[string]bool)
return d
}
@ -639,6 +640,8 @@ func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
value := reflect.New(elemType).Elem()
d.unmarshal(n.children[i+1], value)
inlineMap.SetMapIndex(name, value)
} else if d.strict {
d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in struct %s", n.line+1, name.String(), out.Type()))
}
}
return true

Просмотреть файл

@ -968,6 +968,17 @@ func (s *S) TestUnmarshalSliceOnPreset(c *C) {
c.Assert(v.A, DeepEquals, []int{2})
}
func (s *S) TestUnmarshalStrict(c *C) {
v := struct{ A, B int }{}
err := yaml.UnmarshalStrict([]byte("a: 1\nb: 2"), &v)
c.Check(err, IsNil)
err = yaml.Unmarshal([]byte("a: 1\nb: 2\nc: 3"), &v)
c.Check(err, IsNil)
err = yaml.UnmarshalStrict([]byte("a: 1\nb: 2\nc: 3"), &v)
c.Check(err, ErrorMatches, "yaml: unmarshal errors:\n line 1: field c not found in struct struct { A int; B int }")
}
//var data []byte
//func init() {
// var err error

13
yaml.go
Просмотреть файл

@ -77,8 +77,19 @@ type Marshaler interface {
// supported tag options.
//
func Unmarshal(in []byte, out interface{}) (err error) {
return unmarshal(in, out, false)
}
// UnmarshalStrict is like Unmarshal except that any fields that are found
// in the data that do not have corresponding struct members will result in
// an error.
func UnmarshalStrict(in []byte, out interface{}) (err error) {
return unmarshal(in, out, true)
}
func unmarshal(in []byte, out interface{}, strict bool) (err error) {
defer handleErr(&err)
d := newDecoder()
d := newDecoder(strict)
p := newParser(in)
defer p.destroy()
node := p.parse()