Last active
February 24, 2023 14:59
-
-
Save err0r500/caed5c5c4b6103936dfc1c34c67c3d77 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import zio.* | |
import scala.collection.mutable | |
// TYPES | |
case class Metadata( | |
title: String, | |
description: String, | |
language: String, | |
format: String | |
) | |
case class Doc( | |
metadata: Metadata, | |
content: Array[Byte] | |
) | |
// | |
// metadata repo | |
// | |
trait MetadataRepo: | |
def get: MetadataRepo.Get | |
def put: MetadataRepo.Put | |
object MetadataRepo: | |
type Get = (id: String) => ZIO[Any, Nothing, Option[Metadata]] | |
type Put = (id: String, metadata: Metadata) => ZIO[Any, Nothing, Unit] | |
def put(id: String, metadata: Metadata): ZIO[MetadataRepo, Nothing, Unit] = | |
ZIO.serviceWithZIO[MetadataRepo](_.put(id, metadata)) | |
class MetadataRepoInMem() extends MetadataRepo: | |
private var metadatas: mutable.Map[String, Metadata] = mutable.Map.empty | |
def get: MetadataRepo.Get = (id) => ZIO.succeed(metadatas.get(id)) | |
def put: MetadataRepo.Put = (id, metadata) => | |
ZIO.succeed(metadatas.put(id, metadata)) | |
object MetadataRepoInMem: | |
val layer: ZLayer[Any, Nothing, MetadataRepoInMem] = | |
ZLayer.succeed(new MetadataRepoInMem()) | |
// | |
// blob storage repo | |
// | |
trait BlobStorage: | |
def get: BlobStorage.Get | |
def put: BlobStorage.Put | |
object BlobStorage: | |
type Get = (id: String) => ZIO[Any, Nothing, Option[Array[Byte]]] | |
type Put = (id: String, content: Array[Byte]) => ZIO[Any, Nothing, Unit] | |
class BlobStorageInMem() extends BlobStorage: | |
var blobs: mutable.Map[String, Array[Byte]] = mutable.Map.empty | |
def get: BlobStorage.Get = (id) => ZIO.succeed(blobs.get(id)) | |
def put: BlobStorage.Put = (id, content) => | |
ZIO.succeed(blobs.put(id, content)) | |
object BlobStorageInMem: | |
val layer = ZLayer.succeed(new BlobStorageInMem()) | |
// | |
// doc repo | |
// | |
trait DocRepo: | |
def save: DocRepo.Save | |
def get: DocRepo.Get | |
object DocRepo: | |
type Save = (doc: Doc, id: String) => ZIO[Any, Nothing, Unit] | |
type Get = (id: String) => ZIO[Any, Nothing, Option[Doc]] | |
def save(doc: Doc, id: String): ZIO[DocRepo, Nothing, Unit] = | |
ZIO.serviceWithZIO[DocRepo](_.save(doc, id)) | |
def get(id: String): ZIO[DocRepo, Nothing, Option[Doc]] = | |
ZIO.serviceWithZIO[DocRepo](_.get(id)) | |
// | |
// doc repo live | |
// | |
sealed trait DocRepoLiveErr extends Exception | |
case class MetaNotFound(id: String) extends DocRepoLiveErr | |
case class BlobNotFound(id: String) extends DocRepoLiveErr | |
case class DocRepoLive(MR: MetadataRepo, BSR: BlobStorage) extends DocRepo: | |
def save: DocRepo.Save = (doc, id) => | |
for | |
_ <- MR.put( | |
id, | |
Metadata( | |
doc.metadata.title, | |
doc.metadata.description, | |
doc.metadata.language, | |
doc.metadata.format | |
) | |
) | |
_ <- BSR.put(id, doc.content) | |
yield () | |
def get: DocRepo.Get = (id) => | |
(for | |
metadata <- MR | |
.get(id) | |
.flatMap(_ match | |
case Some(m) => ZIO.succeed(m) | |
case None => ZIO.fail(MetaNotFound(id)) | |
) | |
blob <- BSR | |
.get(id) | |
.flatMap(_ match | |
case Some(m) => ZIO.succeed(m) | |
case None => ZIO.fail(BlobNotFound(id)) | |
) | |
yield Some(Doc(metadata, blob))) | |
.catchAll(e => | |
for _ <- Console.printLine(s"Error $e").catchAll(_ => ZIO.unit) | |
yield None | |
) | |
object DocRepoLive: | |
val layer: ZLayer[MetadataRepo with BlobStorage, Nothing, DocRepo] = | |
ZLayer { | |
for | |
metadataRepo <- ZIO.service[MetadataRepo] | |
blobStorage <- ZIO.service[BlobStorage] | |
yield DocRepoLive(metadataRepo, blobStorage) | |
} | |
// | |
// main | |
// | |
object MainApp extends ZIOAppDefault { | |
val app = for | |
_ <- DocRepo.save( | |
Doc( | |
Metadata("title", "description", "language", "format"), | |
"content".getBytes() | |
), | |
"id" | |
) | |
_ <- DocRepo.get("id").flatMap(doc => Console.printLine(doc.toString)) | |
_ <- DocRepo.get("id2") | |
_ <- MetadataRepo.put( | |
"id3", | |
Metadata("title3", "description3", "language3", "format3") | |
) | |
_ <- DocRepo.get("id3") | |
yield () | |
def run = | |
app.provide( | |
DocRepoLive.layer, | |
MetadataRepoInMem.layer, | |
BlobStorageInMem.layer | |
) | |
} | |
// result (console output) : | |
// | |
// Some(Doc(Metadata(title,description,language,format),[B@57bb2b43)) | |
// Error MetaNotFound | |
// Error BlobNotFound |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment