Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,7 @@ func (s *S) TestMergeNestedStruct(c *C) {
// 2) A simple implementation might attempt to handle the key skipping
// directly by iterating over the merging map without recursion, but
// there are more complex cases that require recursion.
//
//
// Quick summary of the fields:
//
// - A must come from outer and not overriden
Expand All @@ -1497,7 +1497,7 @@ func (s *S) TestMergeNestedStruct(c *C) {
A, B, C int
}
type Outer struct {
D, E int
D, E int
Inner Inner
Inline map[string]int `yaml:",inline"`
}
Expand All @@ -1515,10 +1515,10 @@ func (s *S) TestMergeNestedStruct(c *C) {
// Repeat test with a map.

var testm map[string]interface{}
var wantm = map[string]interface {} {
"f": 60,
var wantm = map[string]interface{}{
"f": 60,
"inner": map[string]interface{}{
"a": 10,
"a": 10,
},
"d": 40,
"e": 50,
Expand Down Expand Up @@ -1614,10 +1614,11 @@ var unmarshalStrictTests = []struct {
value interface{}
error string
}{{
known: true,
data: "a: 1\nc: 2\n",
value: struct{ A, B int }{A: 1},
error: `yaml: unmarshal errors:\n line 2: field c not found in type struct { A int; B int }`,
known: true,
unique: false,
data: "a: 1\nc: 2\n",
value: struct{ A, B int }{A: 1},
error: `yaml: unmarshal errors:\n line 2: field c not found in type struct { A int; B int }`,
}, {
unique: true,
data: "a: 1\nb: 2\na: 3\n",
Expand Down Expand Up @@ -1697,6 +1698,7 @@ func (s *S) TestUnmarshalKnownFields(c *C) {
value := reflect.New(t)
dec := yaml.NewDecoder(bytes.NewBuffer([]byte(item.data)))
dec.KnownFields(item.known)
dec.UniqueKeys(item.unique)
err := dec.Decode(value.Interface())
c.Assert(err, ErrorMatches, item.error)
}
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module "gopkg.in/yaml.v3"
module gopkg.in/yaml.v3

require (
"gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
)
go 1.17

require gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
20 changes: 14 additions & 6 deletions yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,14 @@ type Marshaler interface {
// supported tag options.
//
func Unmarshal(in []byte, out interface{}) (err error) {
return unmarshal(in, out, false)
return unmarshal(in, out)
}

// A Decoder reads and decodes YAML values from an input stream.
type Decoder struct {
parser *parser
knownFields bool
uniqueKeys bool
}

// NewDecoder returns a new decoder that reads from r.
Expand All @@ -101,7 +102,8 @@ type Decoder struct {
// data from r beyond the YAML values requested.
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{
parser: newParserFromReader(r),
parser: newParserFromReader(r),
uniqueKeys: true,
}
}

Expand All @@ -111,6 +113,12 @@ func (dec *Decoder) KnownFields(enable bool) {
dec.knownFields = enable
}

// UniqueKeys enforces the keys in decoded mappings to exist
// only once inside the given mapping.
func (dec *Decoder) UniqueKeys(enable bool) {
dec.uniqueKeys = enable
}

// Decode reads the next YAML-encoded value from its input
// and stores it in the value pointed to by v.
//
Expand All @@ -119,6 +127,7 @@ func (dec *Decoder) KnownFields(enable bool) {
func (dec *Decoder) Decode(v interface{}) (err error) {
d := newDecoder()
d.knownFields = dec.knownFields
d.uniqueKeys = dec.uniqueKeys
defer handleErr(&err)
node := dec.parser.parse()
if node == nil {
Expand Down Expand Up @@ -153,7 +162,7 @@ func (n *Node) Decode(v interface{}) (err error) {
return nil
}

func unmarshal(in []byte, out interface{}, strict bool) (err error) {
func unmarshal(in []byte, out interface{}) (err error) {
defer handleErr(&err)
d := newDecoder()
p := newParser(in)
Expand Down Expand Up @@ -363,7 +372,7 @@ const (
// Address yaml.Node
// }
// err := yaml.Unmarshal(data, &person)
//
//
// Or by itself:
//
// var person Node
Expand All @@ -373,7 +382,7 @@ type Node struct {
// Kind defines whether the node is a document, a mapping, a sequence,
// a scalar value, or an alias to another node. The specific data type of
// scalar nodes may be obtained via the ShortTag and LongTag methods.
Kind Kind
Kind Kind

// Style allows customizing the apperance of the node in the tree.
Style Style
Expand Down Expand Up @@ -421,7 +430,6 @@ func (n *Node) IsZero() bool {
n.HeadComment == "" && n.LineComment == "" && n.FootComment == "" && n.Line == 0 && n.Column == 0
}


// LongTag returns the long form of the tag that indicates the data type for
// the node. If the Tag field isn't explicitly defined, one will be computed
// based on the node properties.
Expand Down