Skip to content

Commit

Permalink
Merge pull request #12 from FelixHerrmann/feature/uttype-conversion
Browse files Browse the repository at this point in the history
[Feature] UTType Conversion
  • Loading branch information
FelixHerrmann authored Oct 16, 2023
2 parents d79455a + 5dc2a36 commit 7f0d345
Show file tree
Hide file tree
Showing 14 changed files with 55 additions and 15 deletions.
9 changes: 6 additions & 3 deletions Sources/MultipartFormData/Boundary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ extension Boundary {

public var debugDescription: String {
switch self {
case .empty: return "Boundary must not be empty."
case .tooLong: return "Boundary is too long. Max size is 70 characters."
case .noASCII: return "Boundary contains at least one character that is not ASCII compatible."
case .empty:
return "Boundary must not be empty."
case .tooLong:
return "Boundary is too long. Max size is 70 characters."
case .noASCII:
return "Boundary contains at least one character that is not ASCII compatible."
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions Sources/MultipartFormData/MediaType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extension MediaType {
public static let multipartFormData = MediaType(type: "multipart", subtype: "form-data")

public static let textPlain = MediaType(type: "text", subtype: "plain")
public static let textCsv = MediaType(type: "text", subtype: "csv")
public static let textHtml = MediaType(type: "text", subtype: "html")
public static let textCss = MediaType(type: "text", subtype: "css")

Expand All @@ -63,6 +64,34 @@ extension MediaType {
}
// swiftlint:enable missing_docs

// MARK: - UniformTypeIdentifiers

#if canImport(UniformTypeIdentifiers)
import UniformTypeIdentifiers

extension MediaType {
/// Create a media type from a uniform type.
/// - Parameter uniformType: The uniform type (UTType).
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
public init?(uniformType: UTType) {
guard let mimeTypeSplit = uniformType.preferredMIMEType?.split(separator: "/") else { return nil }
guard mimeTypeSplit.count == 2 else { return nil }
self.type = String(mimeTypeSplit[0])
self.subtype = String(mimeTypeSplit[1])
}
}

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
extension UTType {
/// Create a uniform type from a media type.
/// - Parameter mediaType: The media type.
/// - Parameter supertype: Another UTType instance that the resulting type must conform to; for example, UTTypeData.
public init?(mediaType: MediaType, conformingTo supertype: UTType = .data) {
self.init(mimeType: mediaType._text, conformingTo: supertype)
}
}
#endif

// MARK: - Debug

extension MediaType: CustomDebugStringConvertible {
Expand Down
1 change: 0 additions & 1 deletion Tests/MultipartFormDataTests/BoundaryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class BoundaryTests: XCTestCase {

func testEmpty() {
XCTAssertThrowsError(try Boundary(uncheckedBoundary: "")) { error in
XCTAssertEqual(error as? Boundary.InvalidBoundaryError, .empty)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class BodyDataBuilderTests: XCTestCase {

func testSingleData() {
let data = _buildData {
Data("a".utf8)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class HTTPHeaderBuilderTests: XCTestCase {

func testAvailableHeaderCombinations() {
let dispositionResult = _buildHeader {
ContentDisposition(name: "a")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class MultipartFormDataBuilderTests: XCTestCase {

func testSingleSubpart() throws {
let subparts = _buildSubparts {
Subpart {
Expand Down
1 change: 0 additions & 1 deletion Tests/MultipartFormDataTests/ContentDispositionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class ContentDispositionTests: XCTestCase {

func testPercentEncodingError() throws {
XCTAssertNoThrow(try ContentDisposition(uncheckedName: "a", uncheckedFilename: "a"))

Expand Down
1 change: 0 additions & 1 deletion Tests/MultipartFormDataTests/ContentTypeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class ContentTypeTests: XCTestCase {

func testBoundaryParameters() throws {
let contentType = ContentType(boundary: try Boundary(uncheckedBoundary: "test"))

Expand Down
1 change: 0 additions & 1 deletion Tests/MultipartFormDataTests/HTTPHeaderFieldTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class HTTPHeaderFieldTests: XCTestCase {

func testDebugDescription() {
let parameter = HTTPHeaderParameter("name", value: "value")
let testHeaderField = TestHeaderField(value: "value", parameters: [parameter])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class HTTPHeaderParameterTests: XCTestCase {

func testArrayText() {
let singleParameter = [
HTTPHeaderParameter("test", value: "a")
Expand Down
21 changes: 20 additions & 1 deletion Tests/MultipartFormDataTests/MediaTypeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
//

import XCTest
#if canImport(UniformTypeIdentifiers)
import UniformTypeIdentifiers
#endif
@testable import MultipartFormData

final class MediaTypeTests: XCTestCase {

func testText() {
let mediaType = MediaType(type: "type", subtype: "subtype")
XCTAssertEqual(mediaType._text, "type/subtype")
Expand All @@ -21,4 +23,21 @@ final class MediaTypeTests: XCTestCase {
let expectedDescription = "type/subtype"
XCTAssertEqual(mediaType.debugDescription, expectedDescription)
}
#if canImport(UniformTypeIdentifiers)

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
func testFromUTTypeConversion() throws {
let uniformType = try XCTUnwrap(UTType("public.comma-separated-values-text"))
let mediaType = try XCTUnwrap(MediaType(uniformType: uniformType))

XCTAssertEqual(mediaType, .textCsv)
}

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
func testToUTTypeConversion() throws {
let uniformType = try XCTUnwrap(UTType(mediaType: .applicationJson))

XCTAssertEqual(uniformType.identifier, "public.json")
}
#endif
}
1 change: 0 additions & 1 deletion Tests/MultipartFormDataTests/MultipartFormDataTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class MultipartFormDataTests: XCTestCase {

func testContentType() throws {
let boundary = try Boundary(uncheckedBoundary: "test")
let multipartFormData = MultipartFormData(boundary: boundary)
Expand Down
1 change: 0 additions & 1 deletion Tests/MultipartFormDataTests/SubpartTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCTest
@testable import MultipartFormData

final class SubpartTests: XCTestCase {

func testDataGeneration() throws {
let subpart = Subpart(
contentDisposition: ContentDisposition(name: "a"),
Expand Down
1 change: 0 additions & 1 deletion Tests/MultipartFormDataTests/URLRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import FoundationNetworking
#endif

final class URLRequestTests: XCTestCase {

func testFormDataInit() throws {
let boundary = try Boundary(uncheckedBoundary: "test")
let multipartFormData = MultipartFormData(boundary: boundary, body: [
Expand Down

0 comments on commit 7f0d345

Please sign in to comment.