I can't resolve the dilemma of whether to use enums with associated values, or to use protocols, for cases where types are loosely related and there will be little or no constraints in the protocol itself. The important thing is not how to store it, but how to use it.
Suppose we have several types that have completely different properties
struct TextOptions {
// ...
}
struct PhotoOptions {
// ...
}
struct VideoOptions {
// ...
}
// etc
The task arises, to store them, but this is not the most important, but the main thing is to have a strictly typed list of all such types and the ability to find out which type is which and to access a concrete type.
The most obvious approach, and what I often see in Rust, is an enum with associated values
enum AnyOptions {
case .text(TextOptions)
case .photo(PhotoOptions)
case .video(VideoOptions)
// etc
}
This approach pretty much meets all my requirements, but the problem is that I don't like it and as far as I can tell Apple's frameworks are not used for this kind of thing.
So we come to the next approach with protocols, and I honestly don't know how to implement it properly.
We start with a protocol
protocol Options {
init?(_ options: borrowing some Options)
}
extension Options {
init?(_ options: borrowing some Options) {
if let anyOptions = _specialize(options, for: AnyOptions.self), let selfOptions = anyOptions.wrappedValue as? Self {
self = selfOptions
} else if let selfOptions = _specialize(options, for: Self.self) {
self = selfOptions
} else {
return nil
}
}
}
We create something like
struct AnyOptions: Options {
let wrapped: any Options
func assumingType<T: Options>(_ type: T.Type) -> T {
guard let options = T(self) else {
preconditionFailure()
}
return options
}
init(_ wrapped: some Options) {
self.wrapped = wrapped
}
}
Now this can be used something like this
let anyOptions = AnyOptions(VideoOptions(...))
let videoOptions = anyOptions.assumingType(VideOptions.self)
But it's not clear to me how to find out the list of available types? Put an additional property enum OptionsType
in the protocol? More questions than answers.
P.S.