Skip to content

Instantly share code, notes, and snippets.

View supermanue's full-sized avatar

Manuel Rodríguez Pascual supermanue

View GitHub Profile
@supermanue
supermanue / doobiePersistenceService.scala
Last active April 5, 2022 06:56
Persistence Service
final class DoobiePersistenceService(tnx: Transactor[Task]) extends StoragePort {
import DoobiePersistenceService._
override def create(user: User): IO[AppError, User] =
SQL
.create(UserStored.fromDomainUser(user))
.run
.transact(tnx)
.foldM(err => IO.fail(DBError(err.getMessage)), _ => IO.succeed(user))
@supermanue
supermanue / zlayer.scala
Last active April 5, 2022 07:04
Zlayer
val live: ZLayer[DBTransactor, Throwable, UserPersistence] =
ZLayer.fromService(new DoobiePersistenceService(_))
val transactorLive: ZLayer[Has[DbConfig] with Blocking, Throwable, DBTransactor] =
ZLayer.fromManaged(for {
config <- configuration.dbConfig.toManaged_
connectEC <- ZIO.descriptor.map(_.executor.asEC).toManaged_
blockingEC <- blocking.blocking { ZIO.descriptor.map(_.executor.asEC) }.toManaged_
transactor <- mkTransactor(config, connectEC, blockingEC)
} yield transactor)
object DoobiePersistenceServiceTest extends DefaultRunnableSpec {
def beforeEach: ZIO[DBTransactor, Throwable, Unit] = dropUserTable.flatMap(_ => createUserTable)
def spec: ZSpec[TestEnvironment, Failure] =
suite("DoobiePersistenceService unit test")(
testM("GET should return a UserNotFound if the element does not exist") {
for {
_ <- beforeEach
notFound <- RIO.accessM[UserPersistence](_.get.get(100).either)
@supermanue
supermanue / motivationForTaggedTypes.scala
Created April 11, 2022 17:14
Motivation for Tagged Types
case class Person(name: String, surname: String)
def getPerson(name: String, surname: String): Person = ???
val person = Person("manuel", "rodriguez")
getPerson(person.surname, person.name)
//doesn't find anything because name and surname are in wrong order
@supermanue
supermanue / betterTypeSystem.scala
Created April 11, 2022 17:17
better type system
case class Person(name: Name, surname: Surname)
def getPerson(name: Name, surname: Surname)
val person = Person("manuel", "Rodriguez")
getPerson(person.surname, person.name)
//DOES NOT COMPILE, THANK YOU GODS OF SCALA
getPerson(person.name, person.surname)
@supermanue
supermanue / taggedTypes.scala
Last active April 11, 2022 17:35
Tagged Types
type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]
trait NameTag
trait SurnameTag
type Name = String @@ NameTag
type Surname = String @@ SurnameTag
(...)