Closed
Description
Let's say I have this structure:
struct Block: Syncable, Transferable {
static var databaseTableName: String { "blocks" }
var id: UUID = UUID()
...
...
...
var type: BlockType // enum
var data: String = ""
var parentId: UUID?
static var parent: BelongsToAssociation<Block, Block> { belongsTo(Block.self, key: "parent") }
var parent: QueryInterfaceRequest<Block> { request(for: Block.parent) }
static var children: HasManyAssociation<Block, Block> { hasMany(Block.self, key: "children") }
var children: QueryInterfaceRequest<Block> { request(for: Block.children) }
enum Columns {
static var type: Column { Column(CodingKeys.type) }
static var data: JSONColumn { JSONColumn(CodingKeys.data) }
static var parentId: Column { Column(CodingKeys.parentId) }
}
init(_ type: BlockType) { self.type = type }
init(_ data: any BlockData) {
self.type = Swift.type(of: data).type
setProperties(data)
}
func getData<T: BlockData>(as type: T.Type) -> T? {
try? JSONDecoder().decode(T.self, from: data.data(using: .utf8)!)
}
mutating func setData<T: BlockData>(_ value: T) {
self.type = T.type
if let data = try? value.toJSON() {
self.data = data
}
}
mutating func setParent(_ parent: Block?) { parentId = parent?.id }
}
Where the data
field is currently represented by a json string. To get this data, you need to call the appropriate methods. But I would like it to have the correct type depending on its content:
struct Block<T: BlockData>: Syncable, Transferable {
...
var data: T // Codable
And if the request for blocks of the same type works well:
struct BlockRequest<T: BlockData>: ValueObservationQueryable {
static var defaultValue: Block<T> { Block<T>(.empty) }
let blockId: UUID
init(_ blockId: UUID) { self.blockId = blockId }
func fetch(_ db: Database) throws -> Block<T> { try Block.find(db, id: blockId) }
}
Then what about those requests that should return blocks of different types?
struct BlocksRequest: ValueObservationQueryable {
static var defaultValue: [Block<any BlockData>] { [] }
Errors:
Type 'BlocksRequest' does not conform to protocol 'Queryable'
Type 'any BlockData' cannot conform to 'BlockData'
Generic parameter 'T' could not be inferred
...
Ideally, I want to make it so that the type of the T block is determined based on its type
field, so that the maximum amount of work is done on the request side and ready-made blocks with the correct types come to the interface. Is this even possible?
Metadata
Metadata
Assignees
Labels
No labels