I've a tree of (different) structs which I want to show in an NSOutlineView. I've also written an update function which determines the move/insert/reload operations on the outline view.
To make the update function more generic, I've written a protocol that makes the different structs similar:
protocol Outlinable: Equatable, Identifiable {
associatedtype T: Outlinable
var children: [T]? { get }
}
The children array is an optional to mark that a node might not have children.
I've made two structs conform to this protocol:
struct ImageWithErrors: Decodable, FetchableRecord {
let imageFile: ImageFile
let imageFileErrors: [ImageFileError]
}
struct LayerImagesListItem: Decodable, FetchableRecord {
let layer: Layer
let imageFiles: [ImageWithErrors]
}
extension LayerImagesListItem: Identifiable, Outlinable {
var id: Int64 { get { layer.id! }}
var children: [ImageWithErrors]? { get { imageFiles }}
}
extension ImageWithErrors: Identifiable, Outlinable {
var id: Int64 { get { -imageFile.id! }}
var children: [Outlinable]? { get { return nil }}
}
The LayerImagesListItem is a root struct, while the ImageWithErrors is (currently) a leave struct. But on this last struct I get the errors:
Type 'ImageWithErrors' does not conform to protocol 'Outlinable'
Protocol 'Outlinable' can only be used as a generic constraint because it has Self or associated type requirements
I've tried replacing [Outlinable] with [Any] but that doesn't solve anything.
How can I tell Swift that ImageWithErrors is never going to return any children?
If
ImageWithErrorscan never have children, you could useNever.It is meant to be used:
but since
ImageWithErrors.childrenis of type[Never]and always returnnilthat should not be an issue.