Given a generic wrapper struct in the following form:
struct Observable<Base> {
var base: Base
}
How can I pass through functionality that is applied to a value of type Observable
to the inner Base
? This can rather easily be done, for instance, with the Equatable
protocol by writing an extension, declaring the requirements func ==
and just calling through to an existing conformance of Base
to Equatable
, like this:
extension Observable: Equatable where Base: Equatable {
static func == (lhs: Observable<Base>, rhs: Observable<Base>) -> Bool {
return lhs.base == rhs.base
}
}
How could I do the same for pattern matching, e.g. so that I can switch
, for example, on a value of type Observable<String?>
directly, just like I would do if it wasn't wrapped in Observable
? An example I'd like to solve and see working would be:
enum Availability {
case available
case notAvailable
}
let observableDescription = Observable<Availability>(.notAvailable)
switch observableDescription {
case .available: // …
case .notAvailable: // …
}
Bonus question: Is it possible to provide conformance to ExpressibleByArrayLiteral
to the generic type Observable
so that I can write let collection: Observable<[Int]> = []
?
Two structs for two questions
Equatable
actually have ~=(_:_:)
as a requirement:
extension Observable: Equatable where Base: Equatable {
static func == (lhs: Observable<Base>, rhs: Observable<Base>) -> Bool {
return lhs.base == rhs.base
}
static func ~= (pattern: Base, value: Self) -> Bool {
pattern ~= value.base
}
}
and now you can just do :
let observableDescription = Observable<Availability>(base: .notAvailable)
switch observableDescription {
case .available:
print("available")
case .notAvailable:
print("notAvailable") // "notAvailable\n"
default:
print("default")
}
ExpressibleByArrayLiteral
For this one you will need an base array:
struct ObservableSequence<Base>: ExpressibleByArrayLiteral where Base: Sequence {
var base: [Base.Element]
init(arrayLiteral elements: Base.Element...) {
base = Array(elements)
}
}
usage:
let emptyCollection: ObservableSequence<[Int]> = []
print(emptyCollection.base) // "[]\n"
let collection: ObservableSequence<[Double]> = [1.0, 3.0, 3.0, 7.0]
print(collection.base) // "[1.0, 3.0, 3.0, 7.0]\n"