softwaremill / softwaremill/macwire

Feature request: support sum type in macwire.

Open
#236 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement Scala3
Dominant language
Scala
Stars
1.3k
Forks
77
Avg merge
9m
Merged PRs (30d)
4

Description

As the code show in gitter

trait DesuConfigModel:
  val configIO: IO[DesuConfig] = ???
end DesuConfigModel

trait AppConfig(config: DesuConfig):
end AppConfig

trait DoobieDB(config: DesuConfig):
  private val dsConfigIO = IO(config.mysqlDesuQuillDB.dataSource)
  val transactor: Resource[IO, HikariTransactor[IO]] = ???
end DoobieDB

trait FileFinder(appConfig: AppConfig, xa: Transactor[IO]):
  // code
end FileFinder

trait AppRoutes(fileFinder: FileFinder, appConfig: AppConfig):
  // code
end AppRoutes

val configModel = wire[DesuConfigModel]
val appRoutes: Resource[IO, AppRoutes] = for
  desuConfig  <- Resource.eval(configModel.configIO)
  appConfig    = wire[AppConfig]
  doobieDB     = wire[DoobieDB]
  xa                <- doobieDB.transactor
yield
  val fileFinder = wire[FileFinder]
  wire[AppRoutes]

Macwire can support wire in F[_] like distage. Since implicit value and constructor value is fetched by type. You can declare a implicit value like

implicit val implicitVarName = constructorVarName

Here request a feature that support sum type in macwire like zio.ZEnvironment. Then we can support something like distage's Module include(simple version) in Scala2 and Scala3.(distage doc)

Here is the code also in gitter

class DesuConfigModelImpl extends DesuConfigModel

class AppConfigImpl(using DesuConfig) extends AppConfig(summon)

class DoobieDBImpl(using DesuConfig) extends DoobieDB(summon)

class FileFinderImpl(using AppConfig, Transactor[IO]) extends FileFinder(summon, summon)

class AppRoutesImpl(using FileFinder, AppConfig) extends AppRoutes(summon, summon)

import zio.{IO as _, *}

object MainAppInjected:

  type ProjectEnvModule1 = DesuConfig & AppConfig & Transactor[IO]

  given [T: Tag, S <: T](using ZEnvironment[S]): T = summon[ZEnvironment[S]].get

  val envResource: Resource[IO, ZEnvironment[ProjectEnvModule1]] = for
    given DesuConfig     <- Resource.eval((new DesuConfigModelImpl).configIO)
    given AppConfig       = new AppConfigImpl
    doobieDB                 = new DoobieDBImpl
    given Transactor[IO] <- doobieDB.transactor
  yield ZEnvironment(implicitly[DesuConfig], implicitly[Transactor[IO]], implicitly[AppConfig])

  val appRoutes: Resource[IO, AppRoutes] = for
    given ZEnvironment[ProjectEnvModule1] <- envResource // distage include(simple version)
  yield
    given FileFinder = new FileFinderImpl
    new AppRoutesImpl

end MainAppInjected

It circuitously performs the macwire function I imagined use Scala3 and zio.ZEnvironment.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the wire[...] entry points and the MainAppInjected example to understand how dependencies are currently resolved. Define how sum-type or environment bindings should be represented and composed, then verify that the requested Scala 3 usage pattern compiles and supports the shown dependency graph.

Written by the indexing model from the issue text.

Assessment

Tech stack
scala
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.