You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.7 KiB

  1. //
  2. // IntegerOperators.swift
  3. // ObjectMapper
  4. //
  5. // Created by Suyeol Jeon on 17/02/2017.
  6. // Copyright © 2017 hearst. All rights reserved.
  7. //
  8. import Foundation
  9. // MARK: - Signed Integer
  10. /// SignedInteger mapping
  11. public func <- <T: SignedInteger>(left: inout T, right: Map) {
  12. switch right.mappingType {
  13. case .fromJSON where right.isKeyPresent:
  14. let value: T = toSignedInteger(right.currentValue) ?? 0
  15. FromJSON.basicType(&left, object: value)
  16. case .toJSON:
  17. left >>> right
  18. default: ()
  19. }
  20. }
  21. /// Optional SignedInteger mapping
  22. public func <- <T: SignedInteger>(left: inout T?, right: Map) {
  23. switch right.mappingType {
  24. case .fromJSON where right.isKeyPresent:
  25. let value: T? = toSignedInteger(right.currentValue)
  26. FromJSON.basicType(&left, object: value)
  27. case .toJSON:
  28. left >>> right
  29. default: ()
  30. }
  31. }
  32. // Code targeting the Swift 4.1 compiler and below.
  33. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  34. /// ImplicitlyUnwrappedOptional SignedInteger mapping
  35. public func <- <T: SignedInteger>(left: inout T!, right: Map) {
  36. switch right.mappingType {
  37. case .fromJSON where right.isKeyPresent:
  38. let value: T! = toSignedInteger(right.currentValue)
  39. FromJSON.basicType(&left, object: value)
  40. case .toJSON:
  41. left >>> right
  42. default: ()
  43. }
  44. }
  45. #endif
  46. // MARK: - Unsigned Integer
  47. /// UnsignedInteger mapping
  48. public func <- <T: UnsignedInteger>(left: inout T, right: Map) {
  49. switch right.mappingType {
  50. case .fromJSON where right.isKeyPresent:
  51. let value: T = toUnsignedInteger(right.currentValue) ?? 0
  52. FromJSON.basicType(&left, object: value)
  53. case .toJSON:
  54. left >>> right
  55. default: ()
  56. }
  57. }
  58. /// Optional UnsignedInteger mapping
  59. public func <- <T: UnsignedInteger>(left: inout T?, right: Map) {
  60. switch right.mappingType {
  61. case .fromJSON where right.isKeyPresent:
  62. let value: T? = toUnsignedInteger(right.currentValue)
  63. FromJSON.basicType(&left, object: value)
  64. case .toJSON:
  65. left >>> right
  66. default: ()
  67. }
  68. }
  69. // Code targeting the Swift 4.1 compiler and below.
  70. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  71. /// ImplicitlyUnwrappedOptional UnsignedInteger mapping
  72. public func <- <T: UnsignedInteger>(left: inout T!, right: Map) {
  73. switch right.mappingType {
  74. case .fromJSON where right.isKeyPresent:
  75. let value: T! = toUnsignedInteger(right.currentValue)
  76. FromJSON.basicType(&left, object: value)
  77. case .toJSON:
  78. left >>> right
  79. default: ()
  80. }
  81. }
  82. #endif
  83. // MARK: - Casting Utils
  84. /// Convert any value to `SignedInteger`.
  85. private func toSignedInteger<T: SignedInteger>(_ value: Any?) -> T? {
  86. guard
  87. let value = value,
  88. case let number as NSNumber = value
  89. else {
  90. return nil
  91. }
  92. if T.self == Int.self, let x = Int(exactly: number.int64Value) {
  93. return T.init(x)
  94. }
  95. if T.self == Int8.self, let x = Int8(exactly: number.int64Value) {
  96. return T.init(x)
  97. }
  98. if T.self == Int16.self, let x = Int16(exactly: number.int64Value) {
  99. return T.init(x)
  100. }
  101. if T.self == Int32.self, let x = Int32(exactly: number.int64Value) {
  102. return T.init(x)
  103. }
  104. if T.self == Int64.self, let x = Int64(exactly: number.int64Value) {
  105. return T.init(x)
  106. }
  107. return nil
  108. }
  109. /// Convert any value to `UnsignedInteger`.
  110. private func toUnsignedInteger<T: UnsignedInteger>(_ value: Any?) -> T? {
  111. guard
  112. let value = value,
  113. case let number as NSNumber = value
  114. else {
  115. return nil
  116. }
  117. if T.self == UInt.self, let x = UInt(exactly: number.uint64Value) {
  118. return T.init(x)
  119. }
  120. if T.self == UInt8.self, let x = UInt8(exactly: number.uint64Value) {
  121. return T.init(x)
  122. }
  123. if T.self == UInt16.self, let x = UInt16(exactly: number.uint64Value) {
  124. return T.init(x)
  125. }
  126. if T.self == UInt32.self, let x = UInt32(exactly: number.uint64Value) {
  127. return T.init(x)
  128. }
  129. if T.self == UInt64.self, let x = UInt64(exactly: number.uint64Value) {
  130. return T.init(x)
  131. }
  132. return nil
  133. }