Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import cats.*
- import cats.syntax.all.*
- import cats.effect.*
- import pureconfig.error.ConfigReaderException
- import pureconfig.{ConfigReader, ConfigSource}
- import scala.annotation.targetName
- import scala.reflect.ClassTag
- trait Module[F[_]: Concurrent, Config, Api, Deps]:
- def loadConfig: Resource[F, Config]
- def deferredApi(dependency: Deps): Resource[F, Deferred[F, Api]] =
- Resource.eval(Deferred.apply)
- def initApi(
- config: Config,
- dependency: Deps,
- uninitializedApi: Deferred[F, Api],
- ): Resource[F, Unit] =
- loadApi(config, dependency).evalMap { api =>
- uninitializedApi.complete(api).void
- }
- @targetName("loadInit")
- final def initApi(
- dependency: Deps,
- uninitializedApi: Deferred[F, Api]
- ): Resource[F, Unit] =
- loadConfig.flatMap(c => initApi(c, dependency, uninitializedApi))
- def loadApi(config: Config, dependency: Deps): Resource[F, Api]
- def loadModule(dependency: Deps): Resource[F, Api] =
- loadConfig.flatMap(c => loadApi(c, dependency))
- protected final def configAt[T: ConfigReader : ClassTag](path: String)(using ApplicativeThrow[F]): Resource[F, T] =
- Resource.eval {
- ApplicativeThrow[F].fromEither {
- ConfigSource.default
- .at(path)
- .load[T]
- .left
- .map(x => new ConfigReaderException[T](x))
- }
- }
- object Module:
- trait Independent[F[_]: Concurrent, Config, Api] extends Module[F, Config, Api, Unit]:
- //Copy defaults just to avoid extra method invocations
- final override def deferredApi(dependency: Unit): Resource[F, Deferred[F, Api]] =
- deferredApi
- final override def initApi(
- config: Config,
- dependency: Unit,
- uninitializedApi: Deferred[F, Api],
- ): Resource[F, Unit] =
- initApi(config, uninitializedApi)
- final override def loadApi(config: Config, dependency: Unit): Resource[F, Api] =
- loadApi(config)
- final override def loadModule(dependency: Unit): Resource[F, Api] =
- loadModule
- def initApi(
- config: Config,
- uninitializedApi: Deferred[F, Api],
- ): Resource[F, Unit] =
- loadApi(config).evalMap { api =>
- uninitializedApi.complete(api).void
- }
- final def initApi(uninitializedApi: Deferred[F, Api]): Resource[F, Unit] =
- loadConfig.flatMap(c => initApi(c, uninitializedApi))
- def loadApi(config: Config): Resource[F, Api]
- def loadModule: Resource[F, Api] =
- loadConfig.flatMap(loadApi)
- def deferredApi: Resource[F, Deferred[F, Api]] =
- Resource.eval(Deferred.apply)
- end Independent
- end Module
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement