From c9eb1bed1f70e4099404812060c34248af3e3bd3 Mon Sep 17 00:00:00 2001 From: kientux Date: Sun, 10 Jul 2022 21:22:12 +0700 Subject: [PATCH] Partially handle enum, add tests --- README.md | 4 +++- Sources/Parameterize/ParamConvertible.swift | 16 ++++++++++++-- .../ParameterizeTests/ParameterizeTests.swift | 22 ++++++++++++++++--- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 873e273..9c02dd1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ components.queryItems = params.map { URLQueryItem(name: $0.key, value: "\($0.val - Auto infer name of param from field name, with default/snake_case or custom naming strategy - Nil and empty array will be remove automatically -- Auto handle array of elements that conform to `CustomStringConvertible` +- Auto handle array (of any elements or elements that conform to `ParamConvertible`) - Auto expand nested params - Support any custom type by conforms to `ParamConvertible`, or simply use an in-place custom mapper @@ -86,6 +86,8 @@ print(serialized) > Note: Conversion will go through custom mapper first, if the returned value also conforms to `ParamConvertible` then it will be converted again using the `ParamConvertible` implementation. +> Note: For enum with raw value, currently there's no easy way to automatically serialize its raw value. So you will still have to conform to `ParamConvertible`, but you don't have to write the `parameterValue` implementation. + ### Nested params will be expanded if also conforms to `ParamsContainer` ```swift diff --git a/Sources/Parameterize/ParamConvertible.swift b/Sources/Parameterize/ParamConvertible.swift index 7eded65..442596a 100644 --- a/Sources/Parameterize/ParamConvertible.swift +++ b/Sources/Parameterize/ParamConvertible.swift @@ -11,12 +11,24 @@ public protocol ParamConvertible { var parameterValue: Any? { get } } -extension Array: ParamConvertible where Element: CustomStringConvertible { +extension Array: ParamConvertible { public var parameterValue: Any? { if isEmpty { return nil } - return map({ $0.description }).joined(separator: ",") + return map({ + if let p = $0 as? ParamConvertible, let v = p.parameterValue { + return String(describing: v) + } else { + return String(describing: $0) + } + }).joined(separator: ",") + } +} + +extension ParamConvertible where Self: RawRepresentable { + var parameterValue: Any? { + String(describing: rawValue) } } diff --git a/Tests/ParameterizeTests/ParameterizeTests.swift b/Tests/ParameterizeTests/ParameterizeTests.swift index 3ea5da5..6b4ba98 100644 --- a/Tests/ParameterizeTests/ParameterizeTests.swift +++ b/Tests/ParameterizeTests/ParameterizeTests.swift @@ -8,7 +8,8 @@ final class ParameterizeTests: XCTestCase { ids: [1, 2, 3], page: 2, pageSize: 250, - productsTypes: ["normal"]) + status: [.active, .inactive], + productsTypes: [.normal]) let serialized = ParamSerializer().serialize(object: params) /// make sure output type is `String`, not `Optional` @@ -19,6 +20,8 @@ final class ParameterizeTests: XCTestCase { XCTAssertEqual(serialized["ids"] as? String, "1,2,3") XCTAssertEqual(serialized["page"] as? Int, 2) XCTAssertEqual(serialized["limit"] as? Int, 250) + XCTAssertEqual(serialized["status"] as? String, "0,-1") + XCTAssertEqual(serialized["product_type"] as? String, "normal") XCTAssertEqual(serialized["product_types"] as? String, "normal") } @@ -114,10 +117,13 @@ struct ProductParams: ParamsContainer { var createdOnMax: Date? = nil @Params - var status: [String] = ["active"] + var status: [Status] = [.active] + + @Params("product_type") + var productsType: ProductType = .normal @Params("product_types") - var productsTypes: [String] = [] + var productsTypes: [ProductType] = [] @Params("custom_type") var myUrl: MyCustomType? = nil @@ -165,6 +171,16 @@ struct ProductParams: ParamsContainer { } } +enum ProductType: String, ParamConvertible { + case normal + case special +} + +enum Status: Int, ParamConvertible { + case active = 0 + case inactive = -1 +} + struct MyCustomType: ParamConvertible { var url: URL