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

增加transformer接口,解决字符串转字典功能无法实现的问题 #418

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
105 changes: 75 additions & 30 deletions Source/BuiltInBasicType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import Foundation

protocol _BuiltInBasicType: _Transformable {

static func _transform(from object: Any) -> Self?
func _plainValue() -> Any?
static func _transform(from object: Any, transformer: _Transformer?) -> Self?
func _plainValue(transformer: _Transformer?) -> Any?
}

// Suppport integer type
Expand All @@ -34,7 +34,10 @@ protocol IntegerPropertyProtocol: FixedWidthInteger, _BuiltInBasicType {

extension IntegerPropertyProtocol {

static func _transform(from object: Any) -> Self? {
static func _transform(from object: Any, transformer: _Transformer?) -> Self? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
switch object {
case let str as String:
return Self(str, radix: 10)
Expand All @@ -45,7 +48,10 @@ extension IntegerPropertyProtocol {
}
}

func _plainValue() -> Any? {
func _plainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
return self
}
}
Expand All @@ -63,7 +69,10 @@ extension UInt64: IntegerPropertyProtocol {}

extension Bool: _BuiltInBasicType {

static func _transform(from object: Any) -> Bool? {
static func _transform(from object: Any, transformer: _Transformer?) -> Bool? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
switch object {
case let str as NSString:
let lowerCase = str.lowercased
Expand All @@ -81,7 +90,10 @@ extension Bool: _BuiltInBasicType {
}
}

func _plainValue() -> Any? {
func _plainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
return self
}
}
Expand All @@ -94,7 +106,10 @@ protocol FloatPropertyProtocol: _BuiltInBasicType, LosslessStringConvertible {

extension FloatPropertyProtocol {

static func _transform(from object: Any) -> Self? {
static func _transform(from object: Any, transformer: _Transformer?) -> Self? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
switch object {
case let str as String:
return Self(str)
Expand All @@ -105,7 +120,10 @@ extension FloatPropertyProtocol {
}
}

func _plainValue() -> Any? {
func _plainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
return self
}
}
Expand All @@ -123,7 +141,10 @@ fileprivate let formatter: NumberFormatter = {

extension String: _BuiltInBasicType {

static func _transform(from object: Any) -> String? {
static func _transform(from object: Any, transformer: _Transformer?) -> String? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
switch object {
case let str as String:
return str
Expand All @@ -144,7 +165,10 @@ extension String: _BuiltInBasicType {
}
}

func _plainValue() -> Any? {
func _plainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
return self
}
}
Expand All @@ -153,8 +177,11 @@ extension String: _BuiltInBasicType {

extension Optional: _BuiltInBasicType {

static func _transform(from object: Any) -> Optional? {
if let value = (Wrapped.self as? _Transformable.Type)?.transform(from: object) as? Wrapped {
static func _transform(from object: Any, transformer: _Transformer?) -> Optional? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
if let value = (Wrapped.self as? _Transformable.Type)?.transform(from: object, transformer: transformer) as? Wrapped {
return Optional(value)
} else if let value = object as? Wrapped {
return Optional(value)
Expand All @@ -168,10 +195,13 @@ extension Optional: _BuiltInBasicType {
})
}

func _plainValue() -> Any? {
func _plainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
if let value = _getWrappedValue() {
if let transformable = value as? _Transformable {
return transformable.plainValue()
return transformable.plainValue(transformer: transformer)
} else {
return value
}
Expand All @@ -184,15 +214,15 @@ extension Optional: _BuiltInBasicType {

extension Collection {

static func _collectionTransform(from object: Any) -> [Iterator.Element]? {
static func _collectionTransform(from object: Any, transformer: _Transformer?) -> [Iterator.Element]? {
guard let arr = object as? [Any] else {
InternalLogger.logDebug("Expect object to be an array but it's not")
return nil
}
typealias Element = Iterator.Element
var result: [Element] = [Element]()
arr.forEach { (each) in
if let element = (Element.self as? _Transformable.Type)?.transform(from: each) as? Element {
if let element = (Element.self as? _Transformable.Type)?.transform(from: each, transformer: transformer) as? Element {
result.append(element)
} else if let element = each as? Element {
result.append(element)
Expand All @@ -201,11 +231,14 @@ extension Collection {
return result
}

func _collectionPlainValue() -> Any? {
func _collectionPlainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
typealias Element = Iterator.Element
var result: [Any] = [Any]()
self.forEach { (each) in
if let transformable = each as? _Transformable, let transValue = transformable.plainValue() {
if let transformable = each as? _Transformable, let transValue = transformable.plainValue(transformer: transformer) {
result.append(transValue)
} else {
InternalLogger.logError("value: \(each) isn't transformable type!")
Expand All @@ -217,42 +250,51 @@ extension Collection {

extension Array: _BuiltInBasicType {

static func _transform(from object: Any) -> [Element]? {
return self._collectionTransform(from: object)
static func _transform(from object: Any, transformer: _Transformer?) -> [Element]? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
return self._collectionTransform(from: object, transformer: transformer)
}

func _plainValue() -> Any? {
return self._collectionPlainValue()
func _plainValue(transformer: _Transformer?) -> Any? {
return self._collectionPlainValue(transformer: transformer)
}
}

extension Set: _BuiltInBasicType {

static func _transform(from object: Any) -> Set<Element>? {
if let arr = self._collectionTransform(from: object) {
static func _transform(from object: Any, transformer: _Transformer?) -> Set<Element>? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
if let arr = self._collectionTransform(from: object, transformer: transformer) {
return Set(arr)
}
return nil
}

func _plainValue() -> Any? {
return self._collectionPlainValue()
func _plainValue(transformer: _Transformer?) -> Any? {
return self._collectionPlainValue(transformer: transformer)
}
}

// MARK: Dictionary Support

extension Dictionary: _BuiltInBasicType {

static func _transform(from object: Any) -> [Key: Value]? {
static func _transform(from object: Any, transformer: _Transformer?) -> [Key: Value]? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
guard let dict = object as? [String: Any] else {
InternalLogger.logDebug("Expect object to be an NSDictionary but it's not")
return nil
}
var result = [Key: Value]()
for (key, value) in dict {
if let sKey = key as? Key {
if let nValue = (Value.self as? _Transformable.Type)?.transform(from: value) as? Value {
if let nValue = (Value.self as? _Transformable.Type)?.transform(from: value, transformer: transformer) as? Value {
result[sKey] = nValue
} else if let nValue = value as? Value {
result[sKey] = nValue
Expand All @@ -262,12 +304,15 @@ extension Dictionary: _BuiltInBasicType {
return result
}

func _plainValue() -> Any? {
func _plainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
var result = [String: Any]()
for (key, value) in self {
if let key = key as? String {
if let transformable = value as? _Transformable {
if let transValue = transformable.plainValue() {
if let transValue = transformable.plainValue(transformer: transformer) {
result[key] = transValue
}
}
Expand Down
41 changes: 28 additions & 13 deletions Source/BuiltInBridgeType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,33 @@ import Foundation

protocol _BuiltInBridgeType: _Transformable {

static func _transform(from object: Any) -> _BuiltInBridgeType?
func _plainValue() -> Any?
static func _transform(from object: Any, transformer: _Transformer?) -> _BuiltInBridgeType?
func _plainValue(transformer: _Transformer?) -> Any?
}

extension NSString: _BuiltInBridgeType {

static func _transform(from object: Any) -> _BuiltInBridgeType? {
if let str = String.transform(from: object) {
static func _transform(from object: Any, transformer: _Transformer?) -> _BuiltInBridgeType? {
if let str = String.transform(from: object, transformer: transformer) {
return NSString(string: str)
}
return nil
}

func _plainValue() -> Any? {
func _plainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
return self
}
}

extension NSNumber: _BuiltInBridgeType {

static func _transform(from object: Any) -> _BuiltInBridgeType? {
static func _transform(from object: Any, transformer: _Transformer?) -> _BuiltInBridgeType? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
switch object {
case let num as NSNumber:
return num
Expand All @@ -51,29 +57,38 @@ extension NSNumber: _BuiltInBridgeType {
}
}

func _plainValue() -> Any? {
func _plainValue(transformer: _Transformer?) -> Any? {
if let result = transformer?.plainValue(from: self) {
return result
}
return self
}
}

extension NSArray: _BuiltInBridgeType {

static func _transform(from object: Any) -> _BuiltInBridgeType? {
static func _transform(from object: Any, transformer: _Transformer?) -> _BuiltInBridgeType? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
return object as? NSArray
}

func _plainValue() -> Any? {
return (self as? Array<Any>)?.plainValue()
func _plainValue(transformer: _Transformer?) -> Any? {
return (self as? Array<Any>)?.plainValue(transformer: transformer)
}
}

extension NSDictionary: _BuiltInBridgeType {

static func _transform(from object: Any) -> _BuiltInBridgeType? {
static func _transform(from object: Any, transformer: _Transformer?) -> _BuiltInBridgeType? {
if let result = transformer?.transform(from: object, type: self) {
return result
}
return object as? NSDictionary
}

func _plainValue() -> Any? {
return (self as? Dictionary<String, Any>)?.plainValue()
func _plainValue(transformer: _Transformer?) -> Any? {
return (self as? Dictionary<String, Any>)?.plainValue(transformer: transformer)
}
}
22 changes: 22 additions & 0 deletions Source/Custom/Transformer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Transformer.swift
// HandyJSON
//
// Created by 熊朝伟 on 2021/1/15.
//

import Foundation

public protocol _Transformer {
func transform<K,V>(from object: Any, type: [K:V].Type) -> [K:V]?
func transform<T>(from object: Any, type: [T].Type) -> [T]?
func transform<T>(from object: Any, type: T.Type) -> T?
func plainValue<T>(from object: T) -> Any?
}

extension _Transformer {
public func transform<K,V>(from object: Any, type: [K:V].Type) -> [K:V]? { nil }
public func transform<T>(from object: Any, type: [T].Type) -> [T]? { nil }
public func transform<T>(from object: Any, type: T.Type) -> T? { nil }
public func plainValue<T>(from object: T) -> Any? { nil }
}
Loading