123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /*
- * Copyright 1999-2101 Alibaba Group.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- // Created by zhouzhuo on 7/7/16.
- //
- import Foundation
- protocol _BuiltInBasicType: _Transformable {
- static func _transform(from object: Any) -> Self?
- func _plainValue() -> Any?
- }
- // Suppport integer type
- protocol IntegerPropertyProtocol: FixedWidthInteger, _BuiltInBasicType {
- init?(_ text: String, radix: Int)
- init(_ number: NSNumber)
- }
- extension IntegerPropertyProtocol {
- static func _transform(from object: Any) -> Self? {
- switch object {
- case let str as String:
- return Self(str, radix: 10)
- case let num as NSNumber:
- return Self(num)
- default:
- return nil
- }
- }
-
- func _plainValue() -> Any? {
- return self
- }
- }
- extension Int: IntegerPropertyProtocol {}
- extension UInt: IntegerPropertyProtocol {}
- extension Int8: IntegerPropertyProtocol {}
- extension Int16: IntegerPropertyProtocol {}
- extension Int32: IntegerPropertyProtocol {}
- extension Int64: IntegerPropertyProtocol {}
- extension UInt8: IntegerPropertyProtocol {}
- extension UInt16: IntegerPropertyProtocol {}
- extension UInt32: IntegerPropertyProtocol {}
- extension UInt64: IntegerPropertyProtocol {}
- extension Bool: _BuiltInBasicType {
- static func _transform(from object: Any) -> Bool? {
- switch object {
- case let str as NSString:
- let lowerCase = str.lowercased
- if ["0", "false"].contains(lowerCase) {
- return false
- }
- if ["1", "true"].contains(lowerCase) {
- return true
- }
- return nil
- case let num as NSNumber:
- return num.boolValue
- default:
- return nil
- }
- }
- func _plainValue() -> Any? {
- return self
- }
- }
- // Support float type
- protocol FloatPropertyProtocol: _BuiltInBasicType, LosslessStringConvertible {
- init(_ number: NSNumber)
- }
- extension FloatPropertyProtocol {
- static func _transform(from object: Any) -> Self? {
- switch object {
- case let str as String:
- return Self(str)
- case let num as NSNumber:
- return Self(num)
- default:
- return nil
- }
- }
- func _plainValue() -> Any? {
- return self
- }
- }
- extension Float: FloatPropertyProtocol {}
- extension Double: FloatPropertyProtocol {}
- fileprivate let formatter: NumberFormatter = {
- let formatter = NumberFormatter()
- formatter.usesGroupingSeparator = false
- formatter.numberStyle = .decimal
- formatter.maximumFractionDigits = 16
- return formatter
- }()
- extension String: _BuiltInBasicType {
- static func _transform(from object: Any) -> String? {
- switch object {
- case let str as String:
- return str
- case let num as NSNumber:
- // Boolean Type Inside
- if NSStringFromClass(type(of: num)) == "__NSCFBoolean" {
- if num.boolValue {
- return "true"
- } else {
- return "false"
- }
- }
- return formatter.string(from: num)
- case _ as NSNull:
- return nil
- default:
- return "\(object)"
- }
- }
- func _plainValue() -> Any? {
- return self
- }
- }
- // MARK: Optional Support
- extension Optional: _BuiltInBasicType {
- static func _transform(from object: Any) -> Optional? {
- if let value = (Wrapped.self as? _Transformable.Type)?.transform(from: object) as? Wrapped {
- return Optional(value)
- } else if let value = object as? Wrapped {
- return Optional(value)
- }
- return nil
- }
- func _getWrappedValue() -> Any? {
- return self.map( { (wrapped) -> Any in
- return wrapped as Any
- })
- }
- func _plainValue() -> Any? {
- if let value = _getWrappedValue() {
- if let transformable = value as? _Transformable {
- return transformable.plainValue()
- } else {
- return value
- }
- }
- return nil
- }
- }
- // MARK: Collection Support : Array & Set
- extension Collection {
- static func _collectionTransform(from object: Any) -> [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 {
- result.append(element)
- } else if let element = each as? Element {
- result.append(element)
- }
- }
- return result
- }
- func _collectionPlainValue() -> Any? {
- typealias Element = Iterator.Element
- var result: [Any] = [Any]()
- self.forEach { (each) in
- if let transformable = each as? _Transformable, let transValue = transformable.plainValue() {
- result.append(transValue)
- } else {
- InternalLogger.logError("value: \(each) isn't transformable type!")
- }
- }
- return result
- }
- }
- extension Array: _BuiltInBasicType {
- static func _transform(from object: Any) -> [Element]? {
- return self._collectionTransform(from: object)
- }
- func _plainValue() -> Any? {
- return self._collectionPlainValue()
- }
- }
- extension Set: _BuiltInBasicType {
- static func _transform(from object: Any) -> Set<Element>? {
- if let arr = self._collectionTransform(from: object) {
- return Set(arr)
- }
- return nil
- }
- func _plainValue() -> Any? {
- return self._collectionPlainValue()
- }
- }
- // MARK: Dictionary Support
- extension Dictionary: _BuiltInBasicType {
- static func _transform(from object: Any) -> [Key: Value]? {
- 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 {
- result[sKey] = nValue
- } else if let nValue = value as? Value {
- result[sKey] = nValue
- }
- }
- }
- return result
- }
- func _plainValue() -> Any? {
- 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() {
- result[key] = transValue
- }
- }
- }
- }
- return result
- }
- }
|