mirror of
https://github.com/samsonjs/Osiris.git
synced 2026-03-25 08:55:48 +00:00
Get rid of some pointless mutable state
This commit is contained in:
parent
0bcf8fe801
commit
012ff20c96
4 changed files with 23 additions and 26 deletions
12
Readme.md
12
Readme.md
|
|
@ -12,17 +12,19 @@ Copy the files you want to use into your project, and then customize them to sui
|
||||||
Create an encoder and then add parts to it as needed:
|
Create an encoder and then add parts to it as needed:
|
||||||
|
|
||||||
```Swift
|
```Swift
|
||||||
let encoder = MultipartFormEncoder()
|
|
||||||
encoder.addPart(.text(name: "email", text: "somebody@example.com"))
|
|
||||||
encoder.addPart(.text(name: "password", text: "secret"))
|
|
||||||
let avatarData = UIImage(from: somewhere).jpegData(compressionQuality: 1)
|
let avatarData = UIImage(from: somewhere).jpegData(compressionQuality: 1)
|
||||||
encoder.addPart(.binary(name: "avatar", type: "image/jpeg", data: avatarData, filename: "avatar.jpg"))
|
let encoder = MultipartFormEncoder()
|
||||||
|
let body = encoder.encode(parts: [
|
||||||
|
.text(name: "email", text: "somebody@example.com"),
|
||||||
|
.text(name: "password", text: "secret"),
|
||||||
|
.binary(name: "avatar", type: "image/jpeg", data: avatarData, filename: "avatar.jpg"),
|
||||||
|
])
|
||||||
```
|
```
|
||||||
|
|
||||||
The entire form is encoded as `Data` in memory so you may not want to use this for more than a few megabytes at a time:
|
The entire form is encoded as `Data` in memory so you may not want to use this for more than a few megabytes at a time:
|
||||||
|
|
||||||
```Swift
|
```Swift
|
||||||
let body = encoder.encode()
|
let body = encoder.encode(parts: [/* ... */])
|
||||||
var request = URLRequest(url: URL(string: "https://example.com/accounts")!)
|
var request = URLRequest(url: URL(string: "https://example.com/accounts")!)
|
||||||
request.httpMethod = "POST"
|
request.httpMethod = "POST"
|
||||||
request.httpBody = body.data
|
request.httpBody = body.data
|
||||||
|
|
|
||||||
|
|
@ -55,17 +55,11 @@ extension MultipartFormEncoder {
|
||||||
final class MultipartFormEncoder {
|
final class MultipartFormEncoder {
|
||||||
let boundary: String
|
let boundary: String
|
||||||
|
|
||||||
private var parts: [Part] = []
|
|
||||||
|
|
||||||
init(boundary: String? = nil) {
|
init(boundary: String? = nil) {
|
||||||
self.boundary = boundary ?? "LifeIsMadeOfSeconds-\(UUID().uuidString)"
|
self.boundary = boundary ?? "LifeIsMadeOfSeconds-\(UUID().uuidString)"
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPart(_ part: Part) {
|
func encode(parts: [Part]) -> Body {
|
||||||
parts.append(part)
|
|
||||||
}
|
|
||||||
|
|
||||||
func encode() -> Body {
|
|
||||||
var bodyData = Data()
|
var bodyData = Data()
|
||||||
for part in parts {
|
for part in parts {
|
||||||
// Header
|
// Header
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,7 @@ final class RequestBuilder {
|
||||||
|
|
||||||
case .multipart:
|
case .multipart:
|
||||||
let encoder = MultipartFormEncoder()
|
let encoder = MultipartFormEncoder()
|
||||||
for part in request.parts {
|
let body = encoder.encode(parts: request.parts)
|
||||||
encoder.addPart(part)
|
|
||||||
}
|
|
||||||
let body = encoder.encode()
|
|
||||||
result.addValue(body.contentType, forHTTPHeaderField: "Content-Type")
|
result.addValue(body.contentType, forHTTPHeaderField: "Content-Type")
|
||||||
result.addValue("\(body.contentLength)", forHTTPHeaderField: "Content-Length")
|
result.addValue("\(body.contentLength)", forHTTPHeaderField: "Content-Length")
|
||||||
result.httpBody = body.data
|
result.httpBody = body.data
|
||||||
|
|
|
||||||
|
|
@ -30,15 +30,14 @@ class MultipartFormEncoderTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncodeNothing() throws {
|
func testEncodeNothing() throws {
|
||||||
let body = subject.encode()
|
let body = subject.encode(parts: [])
|
||||||
XCTAssertEqual(body.contentType, "multipart/form-data; boundary=\"SuperAwesomeBoundary\"")
|
XCTAssertEqual(body.contentType, "multipart/form-data; boundary=\"SuperAwesomeBoundary\"")
|
||||||
AssertBodyEqual(body.data, "--SuperAwesomeBoundary--")
|
AssertBodyEqual(body.data, "--SuperAwesomeBoundary--")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncodeText() throws {
|
func testEncodeText() throws {
|
||||||
subject.addPart(.text(name: "name", value: "Tina"))
|
|
||||||
AssertBodyEqual(
|
AssertBodyEqual(
|
||||||
subject.encode().data,
|
subject.encode(parts: [.text(name: "name", value: "Tina")]).data,
|
||||||
[
|
[
|
||||||
"--SuperAwesomeBoundary",
|
"--SuperAwesomeBoundary",
|
||||||
"Content-Disposition: form-data; name=\"name\"",
|
"Content-Disposition: form-data; name=\"name\"",
|
||||||
|
|
@ -50,9 +49,11 @@ class MultipartFormEncoderTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncodeData() throws {
|
func testEncodeData() throws {
|
||||||
subject.addPart(.binary(name: "video", data: Data("phony video data".utf8), type: "video/mp4", filename: "LiesSex&VideoTape.mp4"))
|
let data = Data("phony video data".utf8)
|
||||||
AssertBodyEqual(
|
AssertBodyEqual(
|
||||||
subject.encode().data,
|
subject.encode(parts: [
|
||||||
|
.binary(name: "video", data: data, type: "video/mp4", filename: "LiesSex&VideoTape.mp4"),
|
||||||
|
]).data,
|
||||||
[
|
[
|
||||||
"--SuperAwesomeBoundary",
|
"--SuperAwesomeBoundary",
|
||||||
"Content-Disposition: form-data; name=\"video\"; filename=\"LiesSex&VideoTape.mp4\"",
|
"Content-Disposition: form-data; name=\"video\"; filename=\"LiesSex&VideoTape.mp4\"",
|
||||||
|
|
@ -66,12 +67,15 @@ class MultipartFormEncoderTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncodeEverything() throws {
|
func testEncodeEverything() throws {
|
||||||
subject.addPart(.text(name: "name", value: "Queso"))
|
let imageData = Data("phony image data".utf8)
|
||||||
subject.addPart(.binary(name: "image", data: Data("phony image data".utf8), type: "image/jpeg", filename: "feltcute.jpg"))
|
let videoData = Data("phony video data".utf8)
|
||||||
subject.addPart(.text(name: "spot", value: "top of the bbq"))
|
|
||||||
subject.addPart(.binary(name: "video", data: Data("phony video data".utf8), type: "video/mp4", filename: "LiesSex&VideoTape.mp4"))
|
|
||||||
AssertBodyEqual(
|
AssertBodyEqual(
|
||||||
subject.encode().data,
|
subject.encode(parts: [
|
||||||
|
.text(name: "name", value: "Queso"),
|
||||||
|
.binary(name: "image", data: imageData, type: "image/jpeg", filename: "feltcute.jpg"),
|
||||||
|
.text(name: "spot", value: "top of the bbq"),
|
||||||
|
.binary(name: "video", data: videoData, type: "video/mp4", filename: "LiesSex&VideoTape.mp4"),
|
||||||
|
]).data,
|
||||||
[
|
[
|
||||||
"--SuperAwesomeBoundary",
|
"--SuperAwesomeBoundary",
|
||||||
"Content-Disposition: form-data; name=\"name\"",
|
"Content-Disposition: form-data; name=\"name\"",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue