@@ -78,7 +78,7 @@ public protocol DocumentBody: DocumentBodyContext {
7878}
7979
8080/// An `EncodableJSONAPIDocument` supports encoding but not decoding.
81- /// It is actually more restrictive than `JSONAPIDocument ` which supports both
81+ /// It is more restrictive than `CodableJSONAPIDocument ` which supports both
8282/// encoding and decoding.
8383public protocol EncodableJSONAPIDocument : Equatable , Encodable , DocumentBodyContext {
8484 associatedtype APIDescription : APIDescriptionType
@@ -103,6 +103,38 @@ public protocol EncodableJSONAPIDocument: Equatable, Encodable, DocumentBodyCont
103103 var apiDescription : APIDescription { get }
104104}
105105
106+ /// A Document that can be constructed as successful (i.e. not an error document).
107+ public protocol SucceedableJSONAPIDocument : EncodableJSONAPIDocument {
108+ /// Create a successful JSONAPI:Document.
109+ ///
110+ /// - Parameters:
111+ /// - apiDescription: The description of the API (a.k.a. the "JSON:API Object").
112+ /// - body: The primary resource body of the JSON:API Document. Generally a single resource or a batch of resources.
113+ /// - includes: All related resources that are included in this Document.
114+ /// - meta: Any metadata associated with the Document.
115+ /// - links: Any links associated with the Document.
116+ ///
117+ init (
118+ apiDescription: APIDescription ,
119+ body: PrimaryResourceBody ,
120+ includes: Includes < IncludeType > ,
121+ meta: MetaType ,
122+ links: LinksType
123+ )
124+ }
125+
126+ /// A Document that can be constructed as failed (i.e. an error document with no primary
127+ /// resource).
128+ public protocol FailableJSONAPIDocument : EncodableJSONAPIDocument {
129+ /// Create an error JSONAPI:Document.
130+ init (
131+ apiDescription: APIDescription ,
132+ errors: [ Error ] ,
133+ meta: MetaType ? ,
134+ links: LinksType ?
135+ )
136+ }
137+
106138/// A `CodableJSONAPIDocument` supports encoding and decoding of a JSON:API
107139/// compliant Document.
108140public protocol CodableJSONAPIDocument : EncodableJSONAPIDocument , Decodable where PrimaryResourceBody: JSONAPI . CodableResourceBody , IncludeType: Decodable { }
@@ -115,7 +147,7 @@ public protocol CodableJSONAPIDocument: EncodableJSONAPIDocument, Decodable wher
115147/// API uses snake case, you will want to use
116148/// a conversion such as the one offerred by the
117149/// Foundation JSONEncoder/Decoder: `KeyDecodingStrategy`
118- public struct Document < PrimaryResourceBody: JSONAPI . EncodableResourceBody , MetaType: JSONAPI . Meta , LinksType: JSONAPI . Links , IncludeType: JSONAPI . Include , APIDescription: APIDescriptionType , Error: JSONAPIError > : EncodableJSONAPIDocument {
150+ public struct Document < PrimaryResourceBody: JSONAPI . EncodableResourceBody , MetaType: JSONAPI . Meta , LinksType: JSONAPI . Links , IncludeType: JSONAPI . Include , APIDescription: APIDescriptionType , Error: JSONAPIError > : EncodableJSONAPIDocument , SucceedableJSONAPIDocument , FailableJSONAPIDocument {
119151 public typealias Include = IncludeType
120152 public typealias BodyData = Body . Data
121153
@@ -125,19 +157,23 @@ public struct Document<PrimaryResourceBody: JSONAPI.EncodableResourceBody, MetaT
125157 // See `EncodableJSONAPIDocument` for documentation.
126158 public let body : Body
127159
128- public init ( apiDescription: APIDescription ,
129- errors: [ Error ] ,
130- meta: MetaType ? = nil ,
131- links: LinksType ? = nil ) {
160+ public init (
161+ apiDescription: APIDescription ,
162+ errors: [ Error ] ,
163+ meta: MetaType ? = nil ,
164+ links: LinksType ? = nil
165+ ) {
132166 body = . errors( errors, meta: meta, links: links)
133167 self . apiDescription = apiDescription
134168 }
135169
136- public init ( apiDescription: APIDescription ,
137- body: PrimaryResourceBody ,
138- includes: Includes < Include > ,
139- meta: MetaType ,
140- links: LinksType ) {
170+ public init (
171+ apiDescription: APIDescription ,
172+ body: PrimaryResourceBody ,
173+ includes: Includes < Include > ,
174+ meta: MetaType ,
175+ links: LinksType
176+ ) {
141177 self . body = . data(
142178 . init(
143179 primary: body,
@@ -449,14 +485,19 @@ extension Document.Body.Data: CustomStringConvertible {
449485extension Document {
450486 /// A Document that only supports error bodies. This is useful if you wish to pass around a
451487 /// Document type but you wish to constrain it to error values.
452- public struct ErrorDocument : EncodableJSONAPIDocument {
488+ public struct ErrorDocument : EncodableJSONAPIDocument , FailableJSONAPIDocument {
453489 public typealias BodyData = Document . BodyData
454490
455491 public var body : Document . Body { return document. body }
456492
457493 private let document : Document
458494
459- public init ( apiDescription: APIDescription , errors: [ Error ] , meta: MetaType ? = nil , links: LinksType ? = nil ) {
495+ public init (
496+ apiDescription: APIDescription ,
497+ errors: [ Error ] ,
498+ meta: MetaType ? = nil ,
499+ links: LinksType ? = nil
500+ ) {
460501 document = . init( apiDescription: apiDescription, errors: errors, meta: meta, links: links)
461502 }
462503
@@ -500,7 +541,7 @@ extension Document {
500541
501542 /// A Document that only supports success bodies. This is useful if you wish to pass around a
502543 /// Document type but you wish to constrain it to success values.
503- public struct SuccessDocument : EncodableJSONAPIDocument {
544+ public struct SuccessDocument : EncodableJSONAPIDocument , SucceedableJSONAPIDocument {
504545 public typealias BodyData = Document . BodyData
505546 public typealias APIDescription = Document . APIDescription
506547 public typealias Body = Document . Body
0 commit comments