Skip to content

Commit 86299d6

Browse files
committed
feat(KeyPaths): Add convenience methods for collections
1 parent a97e733 commit 86299d6

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

Sources/FunctionalKeyPath/FunctionalKeyPath.swift

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Source: https://gist.github.com/maximkrouk/6287fb56321a21e8180d5fe044e642e4
1+
import FunctionalModification
22

33
/// A path that supports embedding a value in a root and attempting to extract a root's embedded
44
/// value.
@@ -138,3 +138,59 @@ public struct FunctionalKeyPath<Root, Value> {
138138
appending(path: path.optional())
139139
}
140140
}
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

Comments
 (0)