@@ -269,6 +269,45 @@ func errTypeMismatch(dstType, srcType reflect.Type) *typeError {
269
269
return & typeError {dstType : dstType , srcType : srcType }
270
270
}
271
271
272
+ type unknownFieldError struct {
273
+ err error
274
+ }
275
+
276
+ func (e * unknownFieldError ) Error () string {
277
+ return e .err .Error ()
278
+ }
279
+
280
+ func errUnknownField (msg string , tk * token.Token ) * unknownFieldError {
281
+ return & unknownFieldError {err : errors .ErrSyntax (msg , tk )}
282
+ }
283
+
284
+ func (d * Decoder ) deleteStructKeys (structValue reflect.Value , unknownFields map [string ]ast.Node ) error {
285
+ strType := structValue .Type ()
286
+ structFieldMap , err := structFieldMap (strType )
287
+ if err != nil {
288
+ return errors .Wrapf (err , "failed to create struct field map" )
289
+ }
290
+
291
+ for j := 0 ; j < strType .NumField (); j ++ {
292
+ field := structValue .Type ().Field (j )
293
+ if isIgnoredStructField (field ) {
294
+ continue
295
+ }
296
+
297
+ structField , ok := structFieldMap [field .Name ]
298
+ if ! ok {
299
+ continue
300
+ }
301
+
302
+ if structField .IsInline {
303
+ d .deleteStructKeys (structValue .FieldByName (field .Name ), unknownFields )
304
+ } else {
305
+ delete (unknownFields , structField .RenderName )
306
+ }
307
+ }
308
+ return nil
309
+ }
310
+
272
311
func (d * Decoder ) decodeValue (dst reflect.Value , src ast.Node ) error {
273
312
valueType := dst .Type ()
274
313
if unmarshaler , ok := dst .Addr ().Interface ().(BytesUnmarshaler ); ok {
@@ -578,10 +617,22 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error {
578
617
te .structFieldName = & fieldName
579
618
}
580
619
foundErr = te
620
+ continue
621
+ }
622
+
623
+ if d .disallowUnknownField {
624
+ var ufe * unknownFieldError
625
+ if ! xerrors .As (err , & ufe ) {
626
+ foundErr = err
627
+ continue
628
+ }
629
+
630
+ if err = d .deleteStructKeys (fieldValue , unknownFields ); err != nil {
631
+ return errors .Wrapf (err , "cannot delete struct keys" )
632
+ }
581
633
} else {
582
- foundErr = err
634
+ continue
583
635
}
584
- continue
585
636
}
586
637
d .setDefaultValueIfConflicted (newFieldValue , structFieldMap )
587
638
fieldValue .Set (d .castToAssignableValue (newFieldValue , fieldValue .Type ()))
@@ -637,7 +688,7 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error {
637
688
}
638
689
if len (unknownFields ) != 0 && d .disallowUnknownField {
639
690
for key , node := range unknownFields {
640
- return errors . ErrSyntax (fmt .Sprintf (`unknown field "%s"` , key ), node .GetToken ())
691
+ return errUnknownField (fmt .Sprintf (`unknown field "%s"` , key ), node .GetToken ())
641
692
}
642
693
}
643
694
if foundErr != nil {
0 commit comments