3232 ErrUnknownFieldNumberType = errors .New ("The struct field was not of a known number type" )
3333 // ErrInvalidType is returned when the given type is incompatible with the expected type.
3434 ErrInvalidType = errors .New ("Invalid type provided" ) // I wish we used punctuation.
35+ // ErrTypeNotFound is returned when the given type not found on the model.
36+ ErrTypeNotFound = errors .New ("no primary type annotation found on model" )
3537)
3638
3739// ErrUnsupportedPtrType is returned when the Struct field was a pointer but
@@ -155,7 +157,13 @@ func jsonapiTypeOfModel(structModel reflect.Type) (string, error) {
155157 for i := 0 ; i < structModel .NumField (); i ++ {
156158 fieldType := structModel .Field (i )
157159 args , err := getStructTags (fieldType )
158- if err != nil || len (args ) < 2 {
160+
161+ // A jsonapi tag was found, but it was improperly structured
162+ if err != nil {
163+ return "" , err
164+ }
165+
166+ if len (args ) < 2 {
159167 continue
160168 }
161169
@@ -164,7 +172,7 @@ func jsonapiTypeOfModel(structModel reflect.Type) (string, error) {
164172 }
165173 }
166174
167- return "" , errors . New ( "no primary annotation found on model" )
175+ return "" , ErrTypeNotFound
168176}
169177
170178// structFieldIndex holds a bit of information about a type found at a struct field index
@@ -175,15 +183,31 @@ type structFieldIndex struct {
175183
176184// choiceStructMapping reflects on a value that may be a slice
177185// of choice type structs or a choice type struct. A choice type
178- // struct is a struct comprising of pointers to other jsonapi models,
186+ // struct is a struct comprised of pointers to other jsonapi models,
179187// only one of which is populated with a value by the decoder.
180188//
181189// The specified type is probed and a map is generated that maps the
182190// underlying model type (its 'primary' type) to the field number
183191// within the choice type struct. This data can then be used to correctly
184192// assign each data relationship node to the correct choice type
185193// struct field.
186- func choiceStructMapping (choice reflect.Type ) (result map [string ]structFieldIndex , err error ) {
194+ //
195+ // For example, if the `choice` type was
196+ //
197+ // type OneOfMedia struct {
198+ // Video *Video
199+ // Image *Image
200+ // }
201+ //
202+ // then the resulting map would be
203+ //
204+ // {
205+ // "videos" => {Video, 0}
206+ // "images" => {Image, 1}
207+ // }
208+ //
209+ // where `"videos"` is the value of the `primary` annotation on the `Video` model
210+ func choiceStructMapping (choice reflect.Type ) (result map [string ]structFieldIndex ) {
187211 result = make (map [string ]structFieldIndex )
188212
189213 for choice .Kind () != reflect .Struct {
@@ -213,7 +237,7 @@ func choiceStructMapping(choice reflect.Type) (result map[string]structFieldInde
213237 }
214238 }
215239
216- return result , nil
240+ return result
217241}
218242
219243func getStructTags (field reflect.StructField ) ([]string , error ) {
@@ -395,11 +419,7 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node)
395419 // struct type field.
396420 var choiceMapping map [string ]structFieldIndex = nil
397421 if annotation == annotationPolyRelation {
398- choiceMapping , err = choiceStructMapping (fieldValue .Type ())
399- if err != nil {
400- er = err
401- break
402- }
422+ choiceMapping = choiceStructMapping (fieldValue .Type ())
403423 }
404424
405425 if isSlice {
0 commit comments