I'm trying to extend optionals into something readable, and achieved this so far:
@discardableResult
func isNotNil(_ handler: (Wrapped) -> Void) -> Optional {
switch self {
case .some(let value):
handler(value)
return self
case .none:
return self
}
}
@discardableResult
func isNil(_ handler: () -> Void) -> Optional {
switch self {
case .some:
return self
case .none:
handler()
return self
}
}
So that I can call my functions on an optional such as:
viewModel?.title.isNotNil { _ in
//do something
}.isNil {
//handle error
}
The problem is, I want to reuse these functions to return specific types, which I'm not able to achieve or am missing something out. For example:
let vm: MyViewModel = dataSource?.heading.isNotNil {
return MyViewModel(title: $0.title, subtitle: $0.subtitle)
}
I've been brainstorming on this and would love some help around this.
Thanks!
What you're doing in your example will raise errors. It boils down to
let vm: MyViewModel
if let heading = dataSource?.heading {
_ = MyViewModel(heading.title, heading.subtitle)
vm = heading
}
So you're trying to assign heading
to vm
(which I am assuming are of different types) and you just construct and drop the MyViewModel
you construct in the closure
What would be a better option is something along these lines:
func mapOptionalOrNot<T>(notNil: (Wrapped) -> T, isNil: () -> T) -> T {
switch self {
case .some(let value):
return notNil(value)
case .none:
return isNil()
}
}
And you could of course give both function default arguments so you can leave them out.
With Swift 5.3s new multi closures you could do something like
let vm: MyViewModel = dataSource?.heading.mapOptionalOrNot { value in
// Map if we have a value
return MyViewModel(title: value.title, subtitle: value.subtitle)
} isNil: {
// Map if we don't have a value
return MyViewModel(title: "Empty", subtitle: "Empty")
}