Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] UTType Conversion #12

Merged
merged 4 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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