Skip to content

Commit

Permalink
Merge pull request #62 from goccy/feature/fix-decoding-for-struct
Browse files Browse the repository at this point in the history
Supports default value in decoding for struct
  • Loading branch information
goccy authored Dec 14, 2019
2 parents 629629f + 6146702 commit 97dfcc5
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
8 changes: 3 additions & 5 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,6 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error {
return nil
}
structType := dst.Type()
structValue := reflect.New(structType)
structFieldMap, err := structFieldMap(structType)
if err != nil {
return errors.Wrapf(err, "failed to create struct field map")
Expand All @@ -555,7 +554,7 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error {
}
structField := structFieldMap[field.Name]
if structField.IsInline {
fieldValue := structValue.Elem().FieldByName(field.Name)
fieldValue := dst.FieldByName(field.Name)
if !fieldValue.CanSet() {
return xerrors.Errorf("cannot set embedded type as unexported field %s.%s", field.PkgPath, field.Name)
}
Expand Down Expand Up @@ -593,7 +592,7 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error {
continue
}
delete(unknownFields, structField.RenderName)
fieldValue := structValue.Elem().FieldByName(field.Name)
fieldValue := dst.FieldByName(field.Name)
if fieldValue.Type().Kind() == reflect.Ptr && src.Type() == ast.NullType {
// set nil value to pointer
fieldValue.Set(reflect.Zero(fieldValue.Type()))
Expand All @@ -617,7 +616,7 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error {
fieldValue.Set(d.castToAssignableValue(newFieldValue, fieldValue.Type()))
}
if d.validator != nil {
if err := d.validator.Struct(structValue.Interface()); err != nil {
if err := d.validator.Struct(dst.Interface()); err != nil {
ev := reflect.ValueOf(err)
if ev.Type().Kind() == reflect.Slice {
for i := 0; i < ev.Len(); i++ {
Expand All @@ -641,7 +640,6 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error {
return errors.ErrSyntax(fmt.Sprintf(`unknown field "%s"`, key), node.GetToken())
}
}
dst.Set(structValue.Elem())
if foundErr != nil {
return errors.Wrapf(foundErr, "failed to decode value")
}
Expand Down
29 changes: 29 additions & 0 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,35 @@ b_yaml: b_yaml_value
}
}

func TestDecoder_DefaultValues(t *testing.T) {
v := struct {
A string `yaml:"a"`
B string `yaml:"b"`
c string // private
}{
B: "defaultBValue",
c: "defaultCValue",
}

const src = `---
a: a_value
`
if err := yaml.NewDecoder(strings.NewReader(src)).Decode(&v); err != nil {
t.Fatalf(`parsing should succeed: %s`, err)
}
if v.A != "a_value" {
t.Fatalf("v.A should be `a_value`, got `%s`", v.A)
}

if v.B != "defaultBValue" {
t.Fatalf("v.B should be `defaultValue`, got `%s`", v.B)
}

if v.c != "defaultCValue" {
t.Fatalf("v.c should be `defaultCValue`, got `%s`", v.c)
}
}

func Example_YAMLTags() {
yml := `---
foo: 1
Expand Down

0 comments on commit 97dfcc5

Please sign in to comment.