Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- private extension StringProtocol {
- init(string: String) {
- self = string as! Self
- }
- }
- indirect enum Path {
- case path(key: String, remainingPath: Path)
- case end(key: String)
- var key: String {
- switch self {
- case let .path(key, _), let .end(key):
- return key
- }
- }
- }
- extension Path {
- init(_ string: String) {
- let segments = string.split(separator: ".", maxSplits: 1)
- if segments.count > 1 {
- self = .path(key: String(segments.first!), remainingPath: Path(String(segments.last!)))
- } else {
- self = .end(key: string)
- }
- }
- }
- extension Path: ExpressibleByStringLiteral {
- init(stringLiteral value: String) {
- self.init(value)
- }
- init(unicodeScalarLiteral value: String) {
- self.init(value)
- }
- init(extendedGraphemeClusterLiteral value: String) {
- self.init(value)
- }
- }
- extension Path: CustomStringConvertible {
- var description: String {
- switch self {
- case .end(let key):
- return key
- case let .path(key, path):
- return "\(key).\(path.description)"
- }
- }
- }
- extension Dictionary where Key: StringProtocol {
- subscript(path keyPath: Path) -> Any? {
- get {
- let key = Key(string: keyPath.key)
- switch keyPath {
- case let .path(_, remainingPath):
- guard let nestedDict = self[key] as? [Key: Any] else {
- return nil
- }
- return nestedDict[path: remainingPath]
- case .end:
- return self[key]
- }
- }
- set {
- let key = Key(string: keyPath.key)
- switch keyPath {
- case .end:
- if let value = newValue {
- self[key] = (value as! Value)
- } else {
- self[key] = nil
- }
- case let .path(_, remainingPath):
- var nestedDict = self[key] as? [Key: Any] ?? [:]
- nestedDict[path: remainingPath] = newValue
- if nestedDict.isEmpty {
- self[key] = nil
- } else {
- self[key] = (nestedDict as! Value)
- }
- }
- }
- }
- }
- var dict: [String: Any] = [
- "language": "de",
- "translator": "Erika Fuchs",
- "translations": [
- "characters": [
- "Scrooge McDuck": "Dagobert",
- "Huey": "Tick",
- "Dewey": "Trick",
- "Louie": "Track",
- "Gyro Gearloose": "Daniel Düsentrieb",
- ],
- "places": [
- "Duckburg": "Entenhausen"
- ]
- ]
- ]
- dict[path: "this.is.a.path"] = "this is a path"
- print(dict[path: "translations.places.Duckburg"])
- dict[path: "translations.places.Duckburg"] = nil
- print(dict)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement