(v any, vt reflect.Type, m *Marshaler)
| 320 | } |
| 321 | |
| 322 | func (d *document) makeResourceObject(v any, vt reflect.Type, m *Marshaler) (*resourceObject, error) { |
| 323 | // the given "v" here is a single resource object |
| 324 | |
| 325 | // first, it must be a struct since we'll be parsing the jsonapi struct tags |
| 326 | if derefType(vt).Kind() != reflect.Struct { |
| 327 | return nil, &TypeError{Actual: vt.String(), Expected: []string{"struct"}} |
| 328 | } |
| 329 | |
| 330 | ro := &resourceObject{ |
| 331 | Attributes: make(map[string]any, 0), |
| 332 | Relationships: make(map[string]*document, 0), |
| 333 | } |
| 334 | |
| 335 | // get fields from embedded structs |
| 336 | fields := getFlattenedFields(v) |
| 337 | |
| 338 | var foundPrimary bool |
| 339 | for _, field := range fields { |
| 340 | // for each field in the struct we'll parse the jsonapi struct tag |
| 341 | // this will determine where it goes in the resource object (e.g. id,type,attributes,...) |
| 342 | |
| 343 | f := field.v |
| 344 | ft := field.f |
| 345 | |
| 346 | tag, err := parseJSONAPITag(ft) |
| 347 | if err != nil { |
| 348 | return nil, err |
| 349 | } |
| 350 | if tag == nil { |
| 351 | // this field is not tagged w/ jsonapi and will be ignored |
| 352 | continue |
| 353 | } |
| 354 | |
| 355 | switch tag.directive { |
| 356 | case primary: |
| 357 | ro.Type = tag.resourceType |
| 358 | if vmt, ok := v.(MarshalType); ok { |
| 359 | ro.Type = vmt.MarshalType() |
| 360 | } |
| 361 | if !isValidMemberName(ro.Type, m.memberNameValidationMode) { |
| 362 | // type names count as member names |
| 363 | return nil, &MemberNameValidationError{ro.Type} |
| 364 | } |
| 365 | |
| 366 | // to marshal the id we follow these rules |
| 367 | // 1. Use MarshalIdentifier if it is implemented |
| 368 | // 2. Use the value directly if it is a string |
| 369 | // 3. Use fmt.Stringer if it is implemented |
| 370 | // 4. Use encoding.TextMarshaler if it is implemented |
| 371 | // 5. Fail |
| 372 | |
| 373 | if vm, ok := v.(MarshalIdentifier); ok { |
| 374 | ro.ID = vm.MarshalID() |
| 375 | foundPrimary = true |
| 376 | continue |
| 377 | } |
| 378 | |
| 379 | fv := f.Interface() |
no test coverage detected