I think there's also at least one intermediate subclass between read-only KeyPath
and CasePath
. It is true that enum case components have three key operations:
- project the value (if it exists), which this proposal provides
- attempt to rewrite the payload in-place in an existing value
- construct an entire new value of the enum, using the given case and a payload
However, if you have a composition of a case component followed by a struct property or tuple element access on the payload, such as \Enum.casePayload?.foo
, then you can only do the first two; since the key path only refers to a partial payload, you can't create an entire new value without an existing value to update. So that suggests to me that you'd have:
// names chosen arbitrarily, not being seriously proposed as is
class ConditionallyWritableKeyPath<Root, Value>: KeyPath<Root, Value?> {
func trySet(in: inout Root, to: Value) throws
}
class CasePath<Root, Value>: ConditionallyWritableKeyPath<Root, Value> {
func embed(_ value: Value) -> Root
}