Skip to content

Commit

Permalink
Add special casing of Data return type (#30)
Browse files Browse the repository at this point in the history
* Special case data when decoding

* Update README
  • Loading branch information
joshuawright11 committed Nov 7, 2023
1 parent 01df204 commit e7eec42
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 15 deletions.
33 changes: 18 additions & 15 deletions PapyrusCore/Sources/Response.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,32 @@ public protocol Response {
}

extension Response {
/// Validates the status code of a Response, as well as any transport errors that may have occurred.
@discardableResult
public func validate() throws -> Self {
if let statusCode {
guard (200..<300).contains(statusCode) else {
throw PapyrusError("Unsuccessful status code: \(statusCode).")
}
}

guard let error else {
return self
if let error { throw error }
if let statusCode, !(200..<300).contains(statusCode) { throw PapyrusError("Unsuccessful status code: \(statusCode).") }
return self
}

public func decode(_ type: Data?.Type = Data?.self, using decoder: ResponseDecoder) throws -> Data? {
try validate().body
}

public func decode(_ type: Data.Type = Data.self, using decoder: ResponseDecoder) throws -> Data {
guard let body = try decode(Data?.self, using: decoder) else {
throw PapyrusError("Unable to return the body of a `Response`; the body was nil.")
}

throw error
return body
}

public func decode<D: Decodable>(_ type: D.Type = D.self, using decoder: ResponseDecoder) throws -> D {
try validate()

guard let data = body else {
guard let body = try validate().body else {
throw PapyrusError("Unable to decode `\(Self.self)` from a `Response`; body was nil.")
}

return try decoder.decode(type, from: data)
return try decoder.decode(type, from: body)
}
}

Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,22 @@ Endpoint functions should return a type that conforms to `Decodable`. It will au
func getUser() async throws -> User
```

### Accessing just the body

If you only need a response's raw body bytes, you can just return `Data` from your function.

```swift
@GET("/bytes")
func getBytes() async throws -> Data
```

The above will throw if the request body is empty, even if the status code is successful. If you don't want to throw in that case, set the response as `Data?`; it will successfully return nil if the response body is empty.

```swift
@GET("/bytes")
func getBytes() async throws -> Data?
```

### Empty responses

If you don't need to decode something from the response and just want to confirm it was successful, you may leave out the return type.
Expand Down

0 comments on commit e7eec42

Please sign in to comment.