Skip to content
This repository has been archived by the owner on Nov 16, 2020. It is now read-only.

Commit

Permalink
Merge pull request #5 from vapor/fix-raw-enum
Browse files Browse the repository at this point in the history
fix encode/decode raw enums
  • Loading branch information
tanner0101 authored Apr 18, 2018
2 parents 741b580 + 764b040 commit 8448fa9
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 40 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/.build
/Packages
/*.xcodeproj
Package.resolved
34 changes: 0 additions & 34 deletions Package.resolved

This file was deleted.

8 changes: 5 additions & 3 deletions Sources/URLEncodedForm/Codable/URLEncodedFormDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,12 @@ private final class _URLEncodedFormSingleValueDecoder: SingleValueDecodingContai
guard let data = context.data.get(at: codingPath) else {
throw DecodingError.typeMismatch(T.self, at: codingPath)
}
guard let convertible = T.self as? URLEncodedFormDataConvertible.Type else {
throw URLEncodedFormError(identifier: "convertible", reason: "Could not convert `\(T.self)` from form-urlencoded data.")
if let convertible = T.self as? URLEncodedFormDataConvertible.Type {
return try convertible.convertFromURLEncodedFormData(data) as! T
} else {
let decoder = _URLEncodedFormDecoder(context: context, codingPath: codingPath)
return try T.init(from: decoder)
}
return try convertible.convertFromURLEncodedFormData(data) as! T
}
}

Expand Down
8 changes: 5 additions & 3 deletions Sources/URLEncodedForm/Codable/URLEncodedFormEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ private final class _URLEncodedFormSingleValueEncoder: SingleValueEncodingContai

/// See `SingleValueEncodingContainer`
func encode<T>(_ value: T) throws where T: Encodable {
guard let convertible = value as? URLEncodedFormDataConvertible else {
throw URLEncodedFormError(identifier: "convertible", reason: "Could not convert `\(T.self)` to form-urlencoded data.")
if let convertible = value as? URLEncodedFormDataConvertible {
try context.data.set(to: convertible.convertToURLEncodedFormData(), at: codingPath)
} else {
let encoder = _URLEncodedFormEncoder(context: context, codingPath: codingPath)
try value.encode(to: encoder)
}
try context.data.set(to: convertible.convertToURLEncodedFormData(), at: codingPath)
}
}

Expand Down
15 changes: 15 additions & 0 deletions Sources/URLEncodedForm/Data/URLEncodedFormDataConvertible.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@ extension BinaryFloatingPoint {
extension Float: URLEncodedFormDataConvertible { }
extension Double: URLEncodedFormDataConvertible { }

extension Bool: URLEncodedFormDataConvertible {
/// See `URLEncodedFormDataConvertible`.
func convertToURLEncodedFormData() throws -> URLEncodedFormData {
return .str(description)
}

/// See `URLEncodedFormDataConvertible`.
static func convertFromURLEncodedFormData(_ data: URLEncodedFormData) throws -> Bool {
guard let bool = data.string?.bool else {
throw URLEncodedFormError(identifier: "bool", reason: "Could not convert to Bool: \(data)")
}
return bool
}
}

extension Dictionary: URLEncodedFormDataConvertible {
/// See `URLEncodedFormDataConvertible`.
func convertToURLEncodedFormData() throws -> URLEncodedFormData {
Expand Down
28 changes: 28 additions & 0 deletions Tests/URLEncodedFormTests/URLEncodedFormCodableTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,39 @@ class URLEncodedFormCodableTests: XCTestCase {
XCTAssertEqual(content["array"], [1, 2, 3])
}

func testRawEnum() throws {
enum PetType: String, Codable {
case cat, dog
}
struct Pet: Codable {
var name: String
var type: PetType
}
let ziz = try URLEncodedFormDecoder().decode(Pet.self, from: "name=Ziz&type=cat")
XCTAssertEqual(ziz.name, "Ziz")
XCTAssertEqual(ziz.type, .cat)
let data = try URLEncodedFormEncoder().encode(ziz)
let string = String(data: data, encoding: .ascii)
XCTAssertEqual(string?.contains("name=Ziz"), true)
XCTAssertEqual(string?.contains("type=cat"), true)
}

/// https://github.com/vapor/url-encoded-form/issues/3
func testGH3() throws {
struct Foo: Codable {
var flag: Bool
}
let foo = try URLEncodedFormDecoder().decode(Foo.self, from: "flag=1")
XCTAssertEqual(foo.flag, true)
}

static let allTests = [
("testDecode", testDecode),
("testEncode", testEncode),
("testCodable", testCodable),
("testDecodeIntArray", testDecodeIntArray),
("testRawEnum", testRawEnum),
("testGH3", testGH3),
]
}

Expand Down

0 comments on commit 8448fa9

Please sign in to comment.