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.

689 lines
24 KiB

  1. //
  2. // TransformOperators.swift
  3. // ObjectMapper
  4. //
  5. // Created by Tristan Himmelman on 2016-09-26.
  6. // Copyright © 2016 hearst. All rights reserved.
  7. //
  8. import Foundation
  9. // MARK:- Transforms
  10. /// Object of Basic type with Transform
  11. public func <- <Transform: TransformType>(left: inout Transform.Object, right: (Map, Transform)) {
  12. let (map, transform) = right
  13. switch map.mappingType {
  14. case .fromJSON where map.isKeyPresent:
  15. let value = transform.transformFromJSON(map.currentValue)
  16. FromJSON.basicType(&left, object: value)
  17. case .toJSON:
  18. left >>> right
  19. default: ()
  20. }
  21. }
  22. public func >>> <Transform: TransformType>(left: Transform.Object, right: (Map, Transform)) {
  23. let (map, transform) = right
  24. if map.mappingType == .toJSON {
  25. let value: Transform.JSON? = transform.transformToJSON(left)
  26. ToJSON.optionalBasicType(value, map: map)
  27. }
  28. }
  29. /// Optional object of basic type with Transform
  30. public func <- <Transform: TransformType>(left: inout Transform.Object?, right: (Map, Transform)) {
  31. let (map, transform) = right
  32. switch map.mappingType {
  33. case .fromJSON where map.isKeyPresent:
  34. let value = transform.transformFromJSON(map.currentValue)
  35. FromJSON.optionalBasicType(&left, object: value)
  36. case .toJSON:
  37. left >>> right
  38. default: ()
  39. }
  40. }
  41. public func >>> <Transform: TransformType>(left: Transform.Object?, right: (Map, Transform)) {
  42. let (map, transform) = right
  43. if map.mappingType == .toJSON {
  44. let value: Transform.JSON? = transform.transformToJSON(left)
  45. ToJSON.optionalBasicType(value, map: map)
  46. }
  47. }
  48. // Code targeting the Swift 4.1 compiler and below.
  49. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  50. /// Implicitly unwrapped optional object of basic type with Transform
  51. public func <- <Transform: TransformType>(left: inout Transform.Object!, right: (Map, Transform)) {
  52. let (map, transform) = right
  53. switch map.mappingType {
  54. case .fromJSON where map.isKeyPresent:
  55. let value = transform.transformFromJSON(map.currentValue)
  56. FromJSON.optionalBasicType(&left, object: value)
  57. case .toJSON:
  58. left >>> right
  59. default: ()
  60. }
  61. }
  62. #endif
  63. /// Array of Basic type with Transform
  64. public func <- <Transform: TransformType>(left: inout [Transform.Object], right: (Map, Transform)) {
  65. let (map, transform) = right
  66. switch map.mappingType {
  67. case .fromJSON where map.isKeyPresent:
  68. let values = fromJSONArrayWithTransform(map.currentValue, transform: transform)
  69. FromJSON.basicType(&left, object: values)
  70. case .toJSON:
  71. left >>> right
  72. default: ()
  73. }
  74. }
  75. public func >>> <Transform: TransformType>(left: [Transform.Object], right: (Map, Transform)) {
  76. let (map, transform) = right
  77. if map.mappingType == .toJSON{
  78. let values = toJSONArrayWithTransform(left, transform: transform)
  79. ToJSON.optionalBasicType(values, map: map)
  80. }
  81. }
  82. /// Optional array of Basic type with Transform
  83. public func <- <Transform: TransformType>(left: inout [Transform.Object]?, right: (Map, Transform)) {
  84. let (map, transform) = right
  85. switch map.mappingType {
  86. case .fromJSON where map.isKeyPresent:
  87. let values = fromJSONArrayWithTransform(map.currentValue, transform: transform)
  88. FromJSON.optionalBasicType(&left, object: values)
  89. case .toJSON:
  90. left >>> right
  91. default: ()
  92. }
  93. }
  94. public func >>> <Transform: TransformType>(left: [Transform.Object]?, right: (Map, Transform)) {
  95. let (map, transform) = right
  96. if map.mappingType == .toJSON {
  97. let values = toJSONArrayWithTransform(left, transform: transform)
  98. ToJSON.optionalBasicType(values, map: map)
  99. }
  100. }
  101. // Code targeting the Swift 4.1 compiler and below.
  102. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  103. /// Implicitly unwrapped optional array of Basic type with Transform
  104. public func <- <Transform: TransformType>(left: inout [Transform.Object]!, right: (Map, Transform)) {
  105. let (map, transform) = right
  106. switch map.mappingType {
  107. case .fromJSON where map.isKeyPresent:
  108. let values = fromJSONArrayWithTransform(map.currentValue, transform: transform)
  109. FromJSON.optionalBasicType(&left, object: values)
  110. case .toJSON:
  111. left >>> right
  112. default: ()
  113. }
  114. }
  115. #endif
  116. /// Dictionary of Basic type with Transform
  117. public func <- <Transform: TransformType>(left: inout [String: Transform.Object], right: (Map, Transform)) {
  118. let (map, transform) = right
  119. switch map.mappingType {
  120. case .fromJSON where map.isKeyPresent:
  121. let values = fromJSONDictionaryWithTransform(map.currentValue, transform: transform)
  122. FromJSON.basicType(&left, object: values)
  123. case .toJSON:
  124. left >>> right
  125. default: ()
  126. }
  127. }
  128. public func >>> <Transform: TransformType>(left: [String: Transform.Object], right: (Map, Transform)) {
  129. let (map, transform) = right
  130. if map.mappingType == . toJSON {
  131. let values = toJSONDictionaryWithTransform(left, transform: transform)
  132. ToJSON.optionalBasicType(values, map: map)
  133. }
  134. }
  135. /// Optional dictionary of Basic type with Transform
  136. public func <- <Transform: TransformType>(left: inout [String: Transform.Object]?, right: (Map, Transform)) {
  137. let (map, transform) = right
  138. switch map.mappingType {
  139. case .fromJSON where map.isKeyPresent:
  140. let values = fromJSONDictionaryWithTransform(map.currentValue, transform: transform)
  141. FromJSON.optionalBasicType(&left, object: values)
  142. case .toJSON:
  143. left >>> right
  144. default: ()
  145. }
  146. }
  147. public func >>> <Transform: TransformType>(left: [String: Transform.Object]?, right: (Map, Transform)) {
  148. let (map, transform) = right
  149. if map.mappingType == .toJSON {
  150. let values = toJSONDictionaryWithTransform(left, transform: transform)
  151. ToJSON.optionalBasicType(values, map: map)
  152. }
  153. }
  154. // Code targeting the Swift 4.1 compiler and below.
  155. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  156. /// Implicitly unwrapped optional dictionary of Basic type with Transform
  157. public func <- <Transform: TransformType>(left: inout [String: Transform.Object]!, right: (Map, Transform)) {
  158. let (map, transform) = right
  159. switch map.mappingType {
  160. case .fromJSON where map.isKeyPresent:
  161. let values = fromJSONDictionaryWithTransform(map.currentValue, transform: transform)
  162. FromJSON.optionalBasicType(&left, object: values)
  163. case .toJSON:
  164. left >>> right
  165. default: ()
  166. }
  167. }
  168. #endif
  169. // MARK:- Transforms of Mappable Objects - <T: BaseMappable>
  170. /// Object conforming to Mappable that have transforms
  171. public func <- <Transform: TransformType>(left: inout Transform.Object, right: (Map, Transform)) where Transform.Object: BaseMappable {
  172. let (map, transform) = right
  173. switch map.mappingType {
  174. case .fromJSON where map.isKeyPresent:
  175. let value: Transform.Object? = transform.transformFromJSON(map.currentValue)
  176. FromJSON.basicType(&left, object: value)
  177. case .toJSON:
  178. left >>> right
  179. default: ()
  180. }
  181. }
  182. public func >>> <Transform: TransformType>(left: Transform.Object, right: (Map, Transform)) where Transform.Object: BaseMappable {
  183. let (map, transform) = right
  184. if map.mappingType == .toJSON {
  185. let value: Transform.JSON? = transform.transformToJSON(left)
  186. ToJSON.optionalBasicType(value, map: map)
  187. }
  188. }
  189. /// Optional Mappable objects that have transforms
  190. public func <- <Transform: TransformType>(left: inout Transform.Object?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  191. let (map, transform) = right
  192. switch map.mappingType {
  193. case .fromJSON where map.isKeyPresent:
  194. let value: Transform.Object? = transform.transformFromJSON(map.currentValue)
  195. FromJSON.optionalBasicType(&left, object: value)
  196. case .toJSON:
  197. left >>> right
  198. default: ()
  199. }
  200. }
  201. public func >>> <Transform: TransformType>(left: Transform.Object?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  202. let (map, transform) = right
  203. if map.mappingType == .toJSON{
  204. let value: Transform.JSON? = transform.transformToJSON(left)
  205. ToJSON.optionalBasicType(value, map: map)
  206. }
  207. }
  208. // Code targeting the Swift 4.1 compiler and below.
  209. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  210. /// Implicitly unwrapped optional Mappable objects that have transforms
  211. public func <- <Transform: TransformType>(left: inout Transform.Object!, right: (Map, Transform)) where Transform.Object: BaseMappable {
  212. let (map, transform) = right
  213. switch map.mappingType {
  214. case .fromJSON where map.isKeyPresent:
  215. let value: Transform.Object? = transform.transformFromJSON(map.currentValue)
  216. FromJSON.optionalBasicType(&left, object: value)
  217. case .toJSON:
  218. left >>> right
  219. default: ()
  220. }
  221. }
  222. #endif
  223. // MARK:- Dictionary of Mappable objects with a transform - Dictionary<String, T: BaseMappable>
  224. /// Dictionary of Mappable objects <String, T: Mappable> with a transform
  225. public func <- <Transform: TransformType>(left: inout Dictionary<String, Transform.Object>, right: (Map, Transform)) where Transform.Object: BaseMappable {
  226. let (map, transform) = right
  227. if map.mappingType == .fromJSON && map.isKeyPresent,
  228. let object = map.currentValue as? [String: Any] {
  229. let value = fromJSONDictionaryWithTransform(object as Any?, transform: transform) ?? left
  230. FromJSON.basicType(&left, object: value)
  231. } else if map.mappingType == .toJSON {
  232. left >>> right
  233. }
  234. }
  235. public func >>> <Transform: TransformType>(left: Dictionary<String, Transform.Object>, right: (Map, Transform)) where Transform.Object: BaseMappable {
  236. let (map, transform) = right
  237. if map.mappingType == .toJSON {
  238. let value = toJSONDictionaryWithTransform(left, transform: transform)
  239. ToJSON.basicType(value, map: map)
  240. }
  241. }
  242. /// Optional Dictionary of Mappable object <String, T: Mappable> with a transform
  243. public func <- <Transform: TransformType>(left: inout Dictionary<String, Transform.Object>?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  244. let (map, transform) = right
  245. if map.mappingType == .fromJSON && map.isKeyPresent, let object = map.currentValue as? [String : Any]{
  246. let value = fromJSONDictionaryWithTransform(object as Any?, transform: transform) ?? left
  247. FromJSON.optionalBasicType(&left, object: value)
  248. } else if map.mappingType == .toJSON {
  249. left >>> right
  250. }
  251. }
  252. public func >>> <Transform: TransformType>(left: Dictionary<String, Transform.Object>?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  253. let (map, transform) = right
  254. if map.mappingType == .toJSON {
  255. let value = toJSONDictionaryWithTransform(left, transform: transform)
  256. ToJSON.optionalBasicType(value, map: map)
  257. }
  258. }
  259. // Code targeting the Swift 4.1 compiler and below.
  260. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  261. /// Implicitly unwrapped Optional Dictionary of Mappable object <String, T: Mappable> with a transform
  262. public func <- <Transform: TransformType>(left: inout Dictionary<String, Transform.Object>!, right: (Map, Transform)) where Transform.Object: BaseMappable {
  263. let (map, transform) = right
  264. if map.mappingType == .fromJSON && map.isKeyPresent, let dictionary = map.currentValue as? [String : Any]{
  265. let transformedDictionary = fromJSONDictionaryWithTransform(dictionary as Any?, transform: transform) ?? left
  266. FromJSON.optionalBasicType(&left, object: transformedDictionary)
  267. } else if map.mappingType == .toJSON {
  268. left >>> right
  269. }
  270. }
  271. #endif
  272. /// Dictionary of Mappable objects <String, T: Mappable> with a transform
  273. public func <- <Transform: TransformType>(left: inout Dictionary<String, [Transform.Object]>, right: (Map, Transform)) where Transform.Object: BaseMappable {
  274. let (map, transform) = right
  275. if let dictionary = map.currentValue as? [String : [Any]], map.mappingType == .fromJSON && map.isKeyPresent {
  276. let transformedDictionary = dictionary.map { (arg: (key: String, values: [Any])) -> (String, [Transform.Object]) in
  277. let (key, values) = arg
  278. if let jsonArray = fromJSONArrayWithTransform(values, transform: transform) {
  279. return (key, jsonArray)
  280. }
  281. if let leftValue = left[key] {
  282. return (key, leftValue)
  283. }
  284. return (key, [])
  285. }
  286. FromJSON.basicType(&left, object: transformedDictionary)
  287. } else if map.mappingType == .toJSON {
  288. left >>> right
  289. }
  290. }
  291. public func >>> <Transform: TransformType>(left: Dictionary<String, [Transform.Object]>, right: (Map, Transform)) where Transform.Object: BaseMappable {
  292. let (map, transform) = right
  293. if map.mappingType == .toJSON {
  294. let transformedDictionary = left.map { (arg: (key: String, value: [Transform.Object])) in
  295. return (arg.key, toJSONArrayWithTransform(arg.value, transform: transform) ?? [])
  296. }
  297. ToJSON.basicType(transformedDictionary, map: map)
  298. }
  299. }
  300. /// Optional Dictionary of Mappable object <String, T: Mappable> with a transform
  301. public func <- <Transform: TransformType>(left: inout Dictionary<String, [Transform.Object]>?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  302. let (map, transform) = right
  303. if let dictionary = map.currentValue as? [String : [Any]], map.mappingType == .fromJSON && map.isKeyPresent {
  304. let transformedDictionary = dictionary.map { (arg: (key: String, values: [Any])) -> (String, [Transform.Object]) in
  305. let (key, values) = arg
  306. if let jsonArray = fromJSONArrayWithTransform(values, transform: transform) {
  307. return (key, jsonArray)
  308. }
  309. if let leftValue = left?[key] {
  310. return (key, leftValue)
  311. }
  312. return (key, [])
  313. }
  314. FromJSON.optionalBasicType(&left, object: transformedDictionary)
  315. } else if map.mappingType == .toJSON {
  316. left >>> right
  317. }
  318. }
  319. public func >>> <Transform: TransformType>(left: Dictionary<String, [Transform.Object]>?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  320. let (map, transform) = right
  321. if map.mappingType == .toJSON {
  322. let transformedDictionary = left?.map { (arg: (key: String, values: [Transform.Object])) in
  323. return (arg.key, toJSONArrayWithTransform(arg.values, transform: transform) ?? [])
  324. }
  325. ToJSON.optionalBasicType(transformedDictionary, map: map)
  326. }
  327. }
  328. // Code targeting the Swift 4.1 compiler and below.
  329. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  330. /// Implicitly unwrapped Optional Dictionary of Mappable object <String, T: Mappable> with a transform
  331. public func <- <Transform: TransformType>(left: inout Dictionary<String, [Transform.Object]>!, right: (Map, Transform)) where Transform.Object: BaseMappable {
  332. let (map, transform) = right
  333. if let dictionary = map.currentValue as? [String : [Any]], map.mappingType == .fromJSON && map.isKeyPresent {
  334. let transformedDictionary = dictionary.map { (arg: (key: String, values: [Any])) -> (String, [Transform.Object]) in
  335. let (key, values) = arg
  336. if let jsonArray = fromJSONArrayWithTransform(values, transform: transform) {
  337. return (key, jsonArray)
  338. }
  339. if let leftValue = left?[key] {
  340. return (key, leftValue)
  341. }
  342. return (key, [])
  343. }
  344. FromJSON.optionalBasicType(&left, object: transformedDictionary)
  345. } else if map.mappingType == .toJSON {
  346. left >>> right
  347. }
  348. }
  349. #endif
  350. // MARK:- Array of Mappable objects with transforms - Array<T: BaseMappable>
  351. /// Array of Mappable objects
  352. public func <- <Transform: TransformType>(left: inout Array<Transform.Object>, right: (Map, Transform)) where Transform.Object: BaseMappable {
  353. let (map, transform) = right
  354. switch map.mappingType {
  355. case .fromJSON where map.isKeyPresent:
  356. if let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) {
  357. FromJSON.basicType(&left, object: transformedValues)
  358. }
  359. case .toJSON:
  360. left >>> right
  361. default: ()
  362. }
  363. }
  364. public func >>> <Transform: TransformType>(left: Array<Transform.Object>, right: (Map, Transform)) where Transform.Object: BaseMappable {
  365. let (map, transform) = right
  366. if map.mappingType == .toJSON {
  367. let transformedValues = toJSONArrayWithTransform(left, transform: transform)
  368. ToJSON.optionalBasicType(transformedValues, map: map)
  369. }
  370. }
  371. /// Optional array of Mappable objects
  372. public func <- <Transform: TransformType>(left: inout Array<Transform.Object>?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  373. let (map, transform) = right
  374. switch map.mappingType {
  375. case .fromJSON where map.isKeyPresent:
  376. let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform)
  377. FromJSON.optionalBasicType(&left, object: transformedValues)
  378. case .toJSON:
  379. left >>> right
  380. default: ()
  381. }
  382. }
  383. public func >>> <Transform: TransformType>(left: Array<Transform.Object>?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  384. let (map, transform) = right
  385. if map.mappingType == .toJSON {
  386. let transformedValues = toJSONArrayWithTransform(left, transform: transform)
  387. ToJSON.optionalBasicType(transformedValues, map: map)
  388. }
  389. }
  390. // Code targeting the Swift 4.1 compiler and below.
  391. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  392. /// Implicitly unwrapped Optional array of Mappable objects
  393. public func <- <Transform: TransformType>(left: inout Array<Transform.Object>!, right: (Map, Transform)) where Transform.Object: BaseMappable {
  394. let (map, transform) = right
  395. switch map.mappingType {
  396. case .fromJSON where map.isKeyPresent:
  397. let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform)
  398. FromJSON.optionalBasicType(&left, object: transformedValues)
  399. case .toJSON:
  400. left >>> right
  401. default: ()
  402. }
  403. }
  404. #endif
  405. // MARK:- Array of Array of objects - Array<Array<T>>> with transforms
  406. /// Array of Array of objects with transform
  407. public func <- <Transform: TransformType>(left: inout [[Transform.Object]], right: (Map, Transform)) {
  408. let (map, transform) = right
  409. switch map.mappingType {
  410. case .toJSON:
  411. left >>> right
  412. case .fromJSON where map.isKeyPresent:
  413. guard let original2DArray = map.currentValue as? [[Any]] else { break }
  414. #if swift(>=4.1)
  415. let transformed2DArray = original2DArray.compactMap { values in
  416. fromJSONArrayWithTransform(values as Any?, transform: transform)
  417. }
  418. #else
  419. let transformed2DArray = original2DArray.flatMap { values in
  420. fromJSONArrayWithTransform(values as Any?, transform: transform)
  421. }
  422. #endif
  423. FromJSON.basicType(&left, object: transformed2DArray)
  424. default:
  425. break
  426. }
  427. }
  428. public func >>> <Transform: TransformType>(left: [[Transform.Object]], right: (Map, Transform)) {
  429. let (map, transform) = right
  430. if map.mappingType == .toJSON{
  431. #if swift(>=4.1)
  432. let transformed2DArray = left.compactMap { values in
  433. toJSONArrayWithTransform(values, transform: transform)
  434. }
  435. #else
  436. let transformed2DArray = left.flatMap { values in
  437. toJSONArrayWithTransform(values, transform: transform)
  438. }
  439. #endif
  440. ToJSON.basicType(transformed2DArray, map: map)
  441. }
  442. }
  443. /// Optional array of array of objects with transform
  444. public func <- <Transform: TransformType>(left: inout [[Transform.Object]]?, right: (Map, Transform)) {
  445. let (map, transform) = right
  446. switch map.mappingType {
  447. case .toJSON:
  448. left >>> right
  449. case .fromJSON where map.isKeyPresent:
  450. guard let original2DArray = map.currentValue as? [[Any]] else { break }
  451. #if swift(>=4.1)
  452. let transformed2DArray = original2DArray.compactMap { values in
  453. fromJSONArrayWithTransform(values as Any?, transform: transform)
  454. }
  455. #else
  456. let transformed2DArray = original2DArray.flatMap { values in
  457. fromJSONArrayWithTransform(values as Any?, transform: transform)
  458. }
  459. #endif
  460. FromJSON.optionalBasicType(&left, object: transformed2DArray)
  461. default:
  462. break
  463. }
  464. }
  465. public func >>> <Transform: TransformType>(left: [[Transform.Object]]?, right: (Map, Transform)) {
  466. let (map, transform) = right
  467. if map.mappingType == .toJSON {
  468. #if swift(>=4.1)
  469. let transformed2DArray = left?.compactMap { values in
  470. toJSONArrayWithTransform(values, transform: transform)
  471. }
  472. #else
  473. let transformed2DArray = left?.flatMap { values in
  474. toJSONArrayWithTransform(values, transform: transform)
  475. }
  476. #endif
  477. ToJSON.optionalBasicType(transformed2DArray, map: map)
  478. }
  479. }
  480. // Code targeting the Swift 4.1 compiler and below.
  481. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  482. /// Implicitly unwrapped Optional array of array of objects with transform
  483. public func <- <Transform: TransformType>(left: inout [[Transform.Object]]!, right: (Map, Transform)) {
  484. let (map, transform) = right
  485. switch map.mappingType {
  486. case .toJSON:
  487. left >>> right
  488. case .fromJSON where map.isKeyPresent:
  489. guard let original2DArray = map.currentValue as? [[Any]] else { break }
  490. #if swift(>=4.1)
  491. let transformed2DArray = original2DArray.compactMap { values in
  492. fromJSONArrayWithTransform(values as Any?, transform: transform)
  493. }
  494. #else
  495. let transformed2DArray = original2DArray.flatMap { values in
  496. fromJSONArrayWithTransform(values as Any?, transform: transform)
  497. }
  498. #endif
  499. FromJSON.optionalBasicType(&left, object: transformed2DArray)
  500. default:
  501. break
  502. }
  503. }
  504. #endif
  505. // MARK:- Set of Mappable objects with a transform - Set<T: BaseMappable>
  506. /// Set of Mappable objects with transform
  507. public func <- <Transform: TransformType>(left: inout Set<Transform.Object>, right: (Map, Transform)) where Transform.Object: BaseMappable {
  508. let (map, transform) = right
  509. switch map.mappingType {
  510. case .fromJSON where map.isKeyPresent:
  511. if let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) {
  512. FromJSON.basicType(&left, object: Set(transformedValues))
  513. }
  514. case .toJSON:
  515. left >>> right
  516. default: ()
  517. }
  518. }
  519. public func >>> <Transform: TransformType>(left: Set<Transform.Object>, right: (Map, Transform)) where Transform.Object: BaseMappable {
  520. let (map, transform) = right
  521. if map.mappingType == .toJSON {
  522. let transformedValues = toJSONArrayWithTransform(Array(left), transform: transform)
  523. ToJSON.optionalBasicType(transformedValues, map: map)
  524. }
  525. }
  526. /// Optional Set of Mappable objects with transform
  527. public func <- <Transform: TransformType>(left: inout Set<Transform.Object>?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  528. let (map, transform) = right
  529. switch map.mappingType {
  530. case .fromJSON where map.isKeyPresent:
  531. if let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) {
  532. FromJSON.basicType(&left, object: Set(transformedValues))
  533. }
  534. case .toJSON:
  535. left >>> right
  536. default: ()
  537. }
  538. }
  539. public func >>> <Transform: TransformType>(left: Set<Transform.Object>?, right: (Map, Transform)) where Transform.Object: BaseMappable {
  540. let (map, transform) = right
  541. if map.mappingType == .toJSON {
  542. if let values = left {
  543. let transformedValues = toJSONArrayWithTransform(Array(values), transform: transform)
  544. ToJSON.optionalBasicType(transformedValues, map: map)
  545. }
  546. }
  547. }
  548. // Code targeting the Swift 4.1 compiler and below.
  549. #if !(swift(>=4.1.50) || (swift(>=3.4) && !swift(>=4.0)))
  550. /// Implicitly unwrapped Optional set of Mappable objects with transform
  551. public func <- <Transform: TransformType>(left: inout Set<Transform.Object>!, right: (Map, Transform)) where Transform.Object: BaseMappable {
  552. let (map, transform) = right
  553. switch map.mappingType {
  554. case .fromJSON where map.isKeyPresent:
  555. if let transformedValues = fromJSONArrayWithTransform(map.currentValue, transform: transform) {
  556. FromJSON.basicType(&left, object: Set(transformedValues))
  557. }
  558. case .toJSON:
  559. left >>> right
  560. default: ()
  561. }
  562. }
  563. #endif
  564. private func fromJSONArrayWithTransform<Transform: TransformType>(_ input: Any?, transform: Transform) -> [Transform.Object]? {
  565. if let values = input as? [Any] {
  566. #if swift(>=4.1)
  567. return values.compactMap { value in
  568. return transform.transformFromJSON(value)
  569. }
  570. #else
  571. return values.flatMap { value in
  572. return transform.transformFromJSON(value)
  573. }
  574. #endif
  575. } else {
  576. return nil
  577. }
  578. }
  579. private func fromJSONDictionaryWithTransform<Transform: TransformType>(_ input: Any?, transform: Transform) -> [String: Transform.Object]? {
  580. if let values = input as? [String: Any] {
  581. return values.filterMap { value in
  582. return transform.transformFromJSON(value)
  583. }
  584. } else {
  585. return nil
  586. }
  587. }
  588. private func toJSONArrayWithTransform<Transform: TransformType>(_ input: [Transform.Object]?, transform: Transform) -> [Transform.JSON]? {
  589. #if swift(>=4.1)
  590. return input?.compactMap { value in
  591. return transform.transformToJSON(value)
  592. }
  593. #else
  594. return input?.flatMap { value in
  595. return transform.transformToJSON(value)
  596. }
  597. #endif
  598. }
  599. private func toJSONDictionaryWithTransform<Transform: TransformType>(_ input: [String: Transform.Object]?, transform: Transform) -> [String: Transform.JSON]? {
  600. return input?.filterMap { value in
  601. return transform.transformToJSON(value)
  602. }
  603. }