-
Notifications
You must be signed in to change notification settings - Fork 104
/
KeyedBox.swift
88 lines (69 loc) · 2.05 KB
/
KeyedBox.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//
// KeyedBox.swift
// XMLCoderPackageDescription
//
// Created by Vincent Esche on 11/19/18.
//
import Foundation
// Minimalist implementation of an order-preserving keyed box:
class KeyedBox {
typealias Key = String
typealias Value = Box
typealias Unboxed = [Key: Value]
private(set) var unboxed: Unboxed
var count: Int {
return self.unboxed.count
}
var keys: Unboxed.Keys {
return self.unboxed.keys
}
subscript(key: Key) -> Value? {
get {
return self.unboxed[key]
}
set {
self.unboxed[key] = newValue
}
}
init(_ unboxed: Unboxed = [:]) {
self.unboxed = unboxed
}
convenience init<S>(_ keysAndValues: S, uniquingKeysWith combine: (Value, Value) throws -> Value) rethrows where S : Sequence, S.Element == (Key, Value) {
let unboxed = try Dictionary(keysAndValues, uniquingKeysWith: combine)
self.init(unboxed)
}
func unbox() -> Unboxed {
return self.unboxed
}
func filter(_ isIncluded: (Key, Value) throws -> Bool) rethrows -> [(Key, Value)] {
return try self.unboxed.filter(isIncluded)
}
func map<T>(_ transform: (Key, Value) throws -> T) rethrows -> [T] {
return try self.unboxed.map(transform)
}
func compactMap<T>(_ transform: ((Key, Value)) throws -> T?) rethrows -> [T] {
return try self.unboxed.compactMap(transform)
}
func mapValues(_ transform: (Value) throws -> Value) rethrows -> KeyedBox {
return KeyedBox(try self.unboxed.mapValues(transform))
}
}
extension KeyedBox: Box {
var isNull: Bool {
return false
}
func xmlString() -> String? {
return nil
}
}
extension KeyedBox: Sequence {
typealias Iterator = Unboxed.Iterator
func makeIterator() -> Iterator {
return self.unboxed.makeIterator()
}
}
extension KeyedBox: CustomStringConvertible {
var description: String {
return self.unboxed.description
}
}