(t reflect.Type)
| 311 | } |
| 312 | |
| 313 | func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc { |
| 314 | // map of json field name to struct field decoders |
| 315 | decoderFields := map[string]decoderField{} |
| 316 | anonymousDecoders := []decoderField{} |
| 317 | extraDecoder := (*decoderField)(nil) |
| 318 | var inlineDecoders []decoderField |
| 319 | |
| 320 | validationEntries := validationRegistry[t] |
| 321 | |
| 322 | for i := 0; i < t.NumField(); i++ { |
| 323 | idx := []int{i} |
| 324 | field := t.FieldByIndex(idx) |
| 325 | if !field.IsExported() { |
| 326 | continue |
| 327 | } |
| 328 | |
| 329 | var validator *validationEntry |
| 330 | for _, entry := range validationEntries { |
| 331 | if entry.field.Offset == field.Offset { |
| 332 | validator = &entry |
| 333 | break |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | // If this is an embedded struct, traverse one level deeper to extract |
| 338 | // the fields and get their encoders as well. |
| 339 | if field.Anonymous { |
| 340 | anonymousDecoders = append(anonymousDecoders, decoderField{ |
| 341 | fn: d.typeDecoder(field.Type), |
| 342 | idx: idx[:], |
| 343 | }) |
| 344 | continue |
| 345 | } |
| 346 | // If json tag is not present, then we skip, which is intentionally |
| 347 | // different behavior from the stdlib. |
| 348 | ptag, ok := parseJSONStructTag(field) |
| 349 | if !ok { |
| 350 | continue |
| 351 | } |
| 352 | // We only want to support unexported fields if they're tagged with |
| 353 | // `extras` because that field shouldn't be part of the public API. |
| 354 | if ptag.extras { |
| 355 | extraDecoder = &decoderField{ptag, d.typeDecoder(field.Type.Elem()), idx, field.Name} |
| 356 | continue |
| 357 | } |
| 358 | if ptag.inline { |
| 359 | df := decoderField{ptag, d.typeDecoder(field.Type), idx, field.Name} |
| 360 | inlineDecoders = append(inlineDecoders, df) |
| 361 | continue |
| 362 | } |
| 363 | if ptag.metadata { |
| 364 | continue |
| 365 | } |
| 366 | |
| 367 | oldFormat := d.dateFormat |
| 368 | dateFormat, ok := parseFormatStructTag(field) |
| 369 | if ok { |
| 370 | switch dateFormat { |
no test coverage detected