Skip to content

Commit

Permalink
Make it possible to use derives Config syntax in Scala 3 (#1479)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyri-petrou authored Nov 7, 2024
1 parent bd3f608 commit 2adb5f2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
19 changes: 19 additions & 0 deletions docs/automatic-derivation-of-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,25 @@ In this case, the config should be
}
```

### Config derivation via `derives` keyword

Scala 3 has introduced `derives` keyword to derive typeclasses without the need of explicitely declaring the implicit / given.
This syntax can be enabled for `zio.Config` by importing `zio.config.magnolia.*` and then using the `derives` keyword on the type that needs to be derived:

```scala 3
import zio.config.magnolia.*
import zio.{Config, ZIO}

sealed trait A
case class B(x: String) extends A
case class C(y: String) extends A

case class MyConfig(a: A) derives Config

// And then simply summon the `Config[MyConfig]` instance as you would normally:
val cfg = ZIO.config[MyConfig]
```

### No guaranteed behavior for scala-3 enum yet
With the current release, there is no guaranteed support of scala-3 enum.
Use `sealed trait` and `case class` pattern.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package zio.config

import zio.ConfigProvider

import zio.Config
import zio.{Config, ConfigProvider}
import zio.IO

import scala.deriving.Mirror

package object magnolia {
def deriveConfig[A](implicit ev: DeriveConfig[A]) =
ev.desc
Expand All @@ -26,4 +26,12 @@ package object magnolia {
def autoLoad[A: DeriveConfig]: IO[Config.Error, A] =
configProvider.load(DeriveConfig[A].desc)
}

/**
* Enables derivation of Config via the `derives Config` syntax
*/
extension (? : Config.type) {
inline def derived[A](using Mirror.Of[A]): Config[A] = DeriveConfig.derived[A].desc
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package zio.config.magnolia

import zio.ConfigProvider
import zio.{Config, ConfigProvider}
import zio.config._
import zio.test.Assertion._
import zio.test._
Expand All @@ -20,6 +20,14 @@ object AutomaticConfigSpec extends ZIOSpecDefault {
val source =
ConfigProvider.fromMap(environment)

assertZIO(source.load(configDesc).either)(isRight)
}
},
test("derives syntax spec") {
check(genEnvironment) { environment =>
val configDesc = summon[Config[MyConfigDerived]]
val source = ConfigProvider.fromMap(environment)

assertZIO(source.load(configDesc).either)(isRight)
}
}
Expand Down Expand Up @@ -63,6 +71,22 @@ object AutomaticConfigTestUtils {
id: UUID
)

final case class MyConfigDerived(
aws: Aws,
cost: Price,
dburl: DbUrl,
port: Int,
amount: Option[Long],
quantity: Either[Long, String],
default: Int = 1,
anotherDefault: Boolean = true,
descriptions: List[String],
created: LocalDate,
updated: LocalTime,
lastVisited: LocalDateTime,
id: UUID
) derives Config

private val genPriceDescription = Gen.const(Description("some description"))
private val genCurrency: Gen[Any, Currency] = Gen.double(10.0, 20.0).map(Currency.apply)
private val genPrice: Gen[Any, Price] = Gen.oneOf(genPriceDescription, genCurrency)
Expand Down

0 comments on commit 2adb5f2

Please sign in to comment.