-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add support for PureConfig (#264)
- Loading branch information
Kevin Chuang
authored
Aug 30, 2024
1 parent
a617545
commit 555940c
Showing
7 changed files
with
139 additions
and
1 deletion.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
title: "PureConfig Support" | ||
--- | ||
|
||
# PureConfig Support | ||
|
||
This module provides refined types ConfigReader instances for [PureConfig](https://pureconfig.github.io/). | ||
|
||
## Dependency | ||
|
||
SBT: | ||
|
||
```scala | ||
libraryDependencies += "io.github.iltotore" %% "iron-pureconfig" % "version" | ||
``` | ||
|
||
Mill: | ||
|
||
```scala | ||
ivy"io.github.iltotore::iron-pureconfig:version" | ||
``` | ||
|
||
### Following examples' dependencies | ||
|
||
SBT: | ||
|
||
```scala | ||
libraryDependencies += "com.github.pureconfig" %% "pureconfig-core" % "0.17.7" | ||
``` | ||
|
||
Mill: | ||
|
||
```scala | ||
ivy"com.github.pureconfig::pureconfig-core::0.17.7" | ||
``` | ||
|
||
## ConfigReader instances | ||
|
||
Iron provides `ConfigReader` instances for refined types: | ||
|
||
```scala | ||
package io.github.iltotore.iron | ||
|
||
import pureconfig.ConfigReader | ||
import pureconfig.generic.derivation.default.* | ||
import io.github.iltotore.iron.constraint.all.* | ||
import io.github.iltotore.iron.pureconfig.given | ||
|
||
opaque type Username = String :| MinLength[5] | ||
object Username extends RefinedTypeOps[String, MinLength[5], Username] | ||
|
||
case class IronTypeConfig( | ||
username: String :| MinLength[5] | ||
) derives ConfigReader | ||
|
||
case class NewTypeConfig( | ||
username: Username | ||
) derives ConfigReader | ||
``` |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package io.github.iltotore.iron | ||
|
||
import _root_.pureconfig.ConfigReader | ||
import _root_.pureconfig.error.FailureReason | ||
|
||
object pureconfig: | ||
final case class RefinedConfigError(description: String) extends FailureReason | ||
|
||
/** | ||
* A [[ConfigReader]] for refined types. Decodes to the underlying type then checks the constraint. | ||
* | ||
* @param reader the [[ConfigReader]] of the underlying type | ||
* @param constraint the [[Constraint]] implementation to test the decoded value | ||
*/ | ||
inline given [A, C](using inline reader: ConfigReader[A], inline constraint: Constraint[A, C]): ConfigReader[A :| C] = | ||
reader | ||
.emap: value => | ||
value | ||
.refineEither[C] | ||
.left | ||
.map(RefinedConfigError(_)) | ||
|
||
/** | ||
* A [[ConfigReader]] for new types. Decodes to the underlying type then checks the constraint | ||
* @param mirror the mirror of the [[RefinedTypeOps.Mirror]] | ||
* @param reader the [[ConfigReader]] of the underlying type | ||
*/ | ||
inline given [A](using mirror: RefinedTypeOps.Mirror[A], reader: ConfigReader[mirror.IronType]): ConfigReader[A] = | ||
reader.asInstanceOf[ConfigReader[A]] |
17 changes: 17 additions & 0 deletions
17
pureconfig/test/src/io/github/iltotore/iron/PureConfigExample.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package io.github.iltotore.iron | ||
|
||
import _root_.pureconfig.ConfigReader | ||
import _root_.pureconfig.generic.derivation.default.* | ||
import io.github.iltotore.iron.constraint.all.* | ||
import io.github.iltotore.iron.pureconfig.given | ||
|
||
opaque type Username = String :| MinLength[5] | ||
object Username extends RefinedTypeOps[String, MinLength[5], Username] | ||
|
||
case class IronTypeConfig( | ||
username: String :| MinLength[5] | ||
) derives ConfigReader | ||
|
||
case class NewTypeConfig( | ||
username: Username | ||
) derives ConfigReader |
18 changes: 18 additions & 0 deletions
18
pureconfig/test/src/io/github/iltotore/iron/PureConfigSuite.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.github.iltotore.iron | ||
|
||
import _root_.pureconfig.ConfigSource | ||
import _root_.pureconfig.generic.derivation.default.* | ||
import utest.* | ||
|
||
object PureConfigSuite extends TestSuite: | ||
|
||
val tests: Tests = Tests: | ||
|
||
test("reader"): | ||
test("ironType"): | ||
test("success") - assert(ConfigSource.string("{ username: admin }").load[IronTypeConfig] == Right(IronTypeConfig("admin"))) | ||
test("failure") - assert(ConfigSource.string("{ username: a }").load[IronTypeConfig].isLeft) | ||
|
||
test("newType"): | ||
test("success") - assert(ConfigSource.string("{ username: admin }").load[NewTypeConfig] == Right(NewTypeConfig(Username("admin")))) | ||
test("failure") - assert(ConfigSource.string("{ username: a }").load[NewTypeConfig].isLeft) |