У меня есть хранилище:
trait CustomerRepo[F[_]] {
def get(id: Identifiable[Customer]): F[Option[CustomerWithId]]
def get(): F[List[CustomerWithId]]
}
У меня есть реализация для моей базы данных, которая использует Cats IO, поэтому у меня есть CustomerRepoPostgres[IO]
.
class CustomerRepoPostgres(xa: Transactor[IO]) extends CustomerRepo[IO] {
import doobie.implicits._
val makeId = IO {
Identifiable[Customer](UUID.randomUUID())
}
override def get(id: Identifiable[Customer]): IO[Option[CustomerWithId]] =
sql"select id, name, active from customer where id = $id"
.query[CustomerWithId].option.transact(xa)
override def get(): IO[List[CustomerWithId]] =
sql"select id, name, active from customer"
.query[CustomerWithId].to[List].transact(xa)
}
Теперь я хочу использовать библиотеку, которая не может работать с произвольными типами держателей (она поддерживает только Future
).Так что мне нужен CustomerRepoPostgres[Future]
.
Я подумал написать какой-нибудь код моста, который может конвертировать мои CustomerRepoPostgres[IO]
в CustomerRepoPostgres[Future]
:
class RepoBridge[F[_]](repo: CustomerRepo[F])
(implicit convertList: F[List[CustomerWithId]] => Future[List[CustomerWithId]],
convertOption: F[Option[CustomerWithId]] => Future[Option[CustomerWithId]]) {
def get(id: Identifiable[Customer]): Future[Option[CustomerWithId]] = repo.get(id)
def get(): Future[List[CustomerWithId]] = repo.get()
}
Мне не нравится этот подходтребует неявных преобразователей для каждого типа, используемого в хранилище.Есть ли лучший способ сделать это?