Created
April 7, 2019 23:51
-
-
Save phronmophobic/ba04374c6004c30c0a990424d6ff4e34 to your computer and use it in GitHub Desktop.
Swift Lens
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
protocol LensProtocol { | |
func lget(data: Any?) -> Any?; | |
func lset(data: Any?, val: Any?) -> Any?; | |
} | |
struct KeyLens<KeyType> : LensProtocol where KeyType : Hashable { | |
let key : KeyType; | |
func lget(data: Any?) -> Any? { | |
if let d = data as? Dictionary<KeyType, Any> { | |
return d[key]; | |
} else { | |
print("oops!") | |
} | |
return nil; | |
} | |
func lset(data: Any?, val: Any?) -> Any?{ | |
if let d = data as? Dictionary<KeyType, Any> { | |
var newd = d; | |
newd[key] = val; | |
return newd; | |
} else { | |
print("oops!") | |
} | |
return nil; | |
} | |
} | |
struct IndexLens : LensProtocol { | |
let index : Int; | |
func lget(data: Any?) -> Any? { | |
if let arr = data as? Array<Any?> { | |
return arr[index]; | |
} else { | |
print("oops!") | |
} | |
return nil; | |
} | |
func lset(data: Any?, val: Any?) -> Any?{ | |
if let arr = data as? Array<Any?> { | |
var newArr = arr; | |
newArr[index] = val; | |
return newArr; | |
} else { | |
print("oops!") | |
} | |
return nil; | |
} | |
} | |
struct ComposeLens : LensProtocol{ | |
let lenses: [LensProtocol]; | |
func lget(data: Any?) -> Any? { | |
var retData = data; | |
for lens in lenses { | |
retData = lens.lget(data: retData); | |
} | |
return retData; | |
} | |
func lset(data: Any?, val: Any?) -> Any? { | |
var retData = data; | |
var original_data : [(LensProtocol, Any?)] = []; | |
let outer_lenses = lenses[0..<lenses.count - 1]; | |
for lens in outer_lenses{ | |
original_data.append((lens, retData)); | |
retData = lens.lget(data: retData); | |
} | |
retData = lenses.last?.lset(data: retData, val:val); | |
for (lens, original_datum) in original_data.reversed(){ | |
retData = lens.lset(data: original_datum, val: retData); | |
} | |
return retData; | |
} | |
}; | |
let todos = ["home": [ ["completed": false, "description": "cook"], | |
["completed": false, "description": "clean"]], | |
"work": [ ["completed": false, "description": "code"], | |
["completed": true, "description": "drink coffee"]] | |
]; | |
print (todos); | |
let first_home_todo_completed_lens = ComposeLens(lenses: [KeyLens(key: "home"), | |
IndexLens(index: 0), | |
KeyLens(key: "completed")]) | |
print(first_home_todo_completed_lens.lset(data: todos, val: true )); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment