|
1 | | -// Source: https://gist.github.com/maximkrouk/6287fb56321a21e8180d5fe044e642e4 |
| 1 | +import FunctionalModification |
2 | 2 |
|
3 | 3 | /// A path that supports embedding a value in a root and attempting to extract a root's embedded |
4 | 4 | /// value. |
@@ -138,3 +138,59 @@ public struct FunctionalKeyPath<Root, Value> { |
138 | 138 | appending(path: path.optional()) |
139 | 139 | } |
140 | 140 | } |
| 141 | + |
| 142 | +extension FunctionalKeyPath { |
| 143 | + public static func key<Key: Hashable, _Value>( |
| 144 | + _ key: Key |
| 145 | + ) -> FunctionalKeyPath |
| 146 | + where Root == Dictionary<Key, _Value>, Value == _Value? { |
| 147 | + FunctionalKeyPath( |
| 148 | + embed: { value, root in |
| 149 | + modification(of: root) { $0[key] = value } |
| 150 | + }, |
| 151 | + extract: { $0[key] } |
| 152 | + ) |
| 153 | + } |
| 154 | + |
| 155 | + public static func index(_ index: Root.Index) -> FunctionalKeyPath |
| 156 | + where Root: MutableCollection, Value == Root.Element { |
| 157 | + FunctionalKeyPath( |
| 158 | + embed: { value, root in |
| 159 | + modification(of: root) { root in |
| 160 | + root[index] = value |
| 161 | + } |
| 162 | + }, |
| 163 | + extract: { root in |
| 164 | + root[index] |
| 165 | + } |
| 166 | + ) |
| 167 | + } |
| 168 | + |
| 169 | + public static func getonlyIndex(_ index: Root.Index) -> FunctionalKeyPath |
| 170 | + where Root: Collection, Value == Root.Element { |
| 171 | + FunctionalKeyPath( |
| 172 | + embed: { _, root in return root }, |
| 173 | + extract: { $0[index] } |
| 174 | + ) |
| 175 | + } |
| 176 | + |
| 177 | + public static func safeIndex(_ index: Root.Index) -> FunctionalKeyPath<Root, Value?> |
| 178 | + where Root == [Value] { |
| 179 | + FunctionalKeyPath<Root, Value?>( |
| 180 | + embed: { value, root in |
| 181 | + modification(of: root) { root in |
| 182 | + guard |
| 183 | + let value = value, |
| 184 | + root.indices.contains(index) |
| 185 | + else { return } |
| 186 | + root[index] = value |
| 187 | + } |
| 188 | + }, |
| 189 | + extract: { root in |
| 190 | + return root.indices.contains(index) |
| 191 | + ? root[index] |
| 192 | + : nil |
| 193 | + } |
| 194 | + ) |
| 195 | + } |
| 196 | +} |
0 commit comments