I'm working on an abstraction to hide the specifics of ObjectBox database from my app.
class ObjectBoxDatabase: Database {
func all<T>(of type: T.Type) throws -> [T] where T : DatabaseEntity {
let box = self.getBox(for: T.self)
return box?.all() ?? []
}
private func getBox<T>(for type: T.Type) -> Box<T>? where T : DatabaseEntity {
switch T.self {
case is SomeEntity.Type:
return someEntityBox as? Box<T>
case is SomeOtherEntity.Type:
return someOtherEntityBox as? Box<T>
default:
return nil
}
}
}
The implementation of getBox
is just a placeholder for now, I'm planning on implementing some more advanced logic there once I figure out the generics.
My problem is that this way, the compiler is complaining when I'm calling getBox
that T
needs to conform __EntityRelatable
, EntityInspectable
and T.EntityBindingTypeEntityType == T
.
Box<E> : CustomDebugStringConvertible where E : ObjectBox.EntityInspectable, E : ObjectBox.__EntityRelatable, E == E.EntityBindingType.EntityType
I think if it was only one requirement, I could cast T
and pass it that way but since these 3 are not related, I don't know what to cast to that is all three and DatabaseEntity at the same time.
An other option I was thinking was to not return Box<T>
from getBox
but something else, this way T
doesn't get restricted. The problem is I don't know what to return then as I don't have a common type (again)
My final try was, (I know from design perspective it is not a good approach at all, but I wanted to see some code running finally) to conform my DatabaseEntity
to all those requirements and return Box<DatabaseEntity>
but then I still get any DatabaseEntity does not conform EntityInspectable
on the return type
EDIT
someEntityBox
and someOtherEntityBox
are Box<SomeEntity>
and Box< SomeOtherEntity>
respectively where those entities conform to the Entity
protocol from ObjectBox
The database entity protocol is just an empty protocol for now
protocol DatabaseEntity {}