-
Notifications
You must be signed in to change notification settings - Fork 175
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into update/scala-xml-2.0.0
- Loading branch information
Showing
126 changed files
with
2,037 additions
and
793 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,3 +28,6 @@ target/ | |
.bloop/ | ||
.metals/ | ||
metals.sbt | ||
|
||
# vscode specific | ||
.vscode |
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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
version = 3.0.0-RC1 | ||
version = 3.0.0-RC5 | ||
|
||
align.preset = none | ||
maxColumn = 120 | ||
|
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
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
24 changes: 24 additions & 0 deletions
24
core/src/main/scala-3/pureconfig/generic/derivation/ConfigReaderDerivation.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,24 @@ | ||
package pureconfig | ||
package generic | ||
package derivation | ||
|
||
import scala.deriving.Mirror | ||
|
||
trait ConfigReaderDerivation extends CoproductConfigReaderDerivation with ProductConfigReaderDerivation { | ||
extension (c: ConfigReader.type) { | ||
inline def derived[A](using m: Mirror.Of[A]): ConfigReader[A] = | ||
inline m match { | ||
case given Mirror.ProductOf[A] => derivedProduct | ||
case given Mirror.SumOf[A] => derivedSum | ||
} | ||
} | ||
} | ||
|
||
object ConfigReaderDerivation { | ||
object Default | ||
extends ConfigReaderDerivation | ||
with CoproductConfigReaderDerivation(ConfigFieldMapping(PascalCase, KebabCase), "type") | ||
with ProductConfigReaderDerivation(ConfigFieldMapping(CamelCase, KebabCase)) | ||
} | ||
|
||
val default = ConfigReaderDerivation.Default |
56 changes: 56 additions & 0 deletions
56
core/src/main/scala-3/pureconfig/generic/derivation/CoproductConfigReaderDerivation.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,56 @@ | ||
package pureconfig | ||
package generic | ||
package derivation | ||
|
||
import scala.compiletime.{constValue, erasedValue, summonFrom, summonInline} | ||
import scala.deriving.Mirror | ||
|
||
import pureconfig.error.{CannotConvert, ConfigReaderFailures} | ||
import pureconfig.generic.derivation.ConfigReaderDerivation | ||
import pureconfig.generic.derivation.WidenType.widen | ||
|
||
trait CoproductConfigReaderDerivation(fieldMapping: ConfigFieldMapping, optionField: String) { | ||
self: ConfigReaderDerivation => | ||
inline def derivedSum[A](using m: Mirror.SumOf[A]): ConfigReader[A] = | ||
new ConfigReader[A] { | ||
def from(cur: ConfigCursor): ConfigReader.Result[A] = | ||
for { | ||
objCur <- cur.asObjectCursor | ||
optCur <- objCur.atKey(optionField) | ||
option <- optCur.asString | ||
result <- | ||
readers.get(option) match { | ||
case Some(reader) => reader.from(cur) | ||
case None => | ||
Left( | ||
ConfigReaderFailures( | ||
optCur.failureFor( | ||
CannotConvert(option, constValue[m.MirroredLabel], "The value is not a valid option.") | ||
) | ||
) | ||
) | ||
} | ||
} yield result | ||
|
||
val readers = | ||
Labels | ||
.transformed[m.MirroredElemLabels](fieldMapping) | ||
.zip(deriveForSubtypes[m.MirroredElemTypes, A]) | ||
.toMap | ||
} | ||
|
||
inline def deriveForSubtypes[T <: Tuple, A]: List[ConfigReader[A]] = | ||
inline erasedValue[T] match { | ||
case _: (h *: t) => deriveForSubtype[h, A] :: deriveForSubtypes[t, A] | ||
case _: EmptyTuple => Nil | ||
} | ||
|
||
inline def deriveForSubtype[A0, A]: ConfigReader[A] = | ||
summonFrom { | ||
case reader: ConfigReader[A0] => | ||
reader.map(widen[A0, A](_)) | ||
|
||
case given Mirror.Of[A0] => | ||
ConfigReader.derived[A0].map(widen[A0, A](_)) | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
core/src/main/scala-3/pureconfig/generic/derivation/EnumConfigReaderDerivation.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,64 @@ | ||
package pureconfig | ||
package generic | ||
package derivation | ||
|
||
import scala.compiletime.{constValue, erasedValue, error, summonInline} | ||
import scala.deriving.Mirror | ||
|
||
import pureconfig.error.{CannotConvert, ConfigReaderFailures} | ||
import pureconfig.generic.derivation.WidenType.widen | ||
|
||
type EnumConfigReader[A] = EnumConfigReaderDerivation.Default.EnumConfigReader[A] | ||
|
||
trait EnumConfigReaderDerivation(transformName: String => String) { | ||
|
||
trait EnumConfigReader[A] extends ConfigReader[A] | ||
|
||
object EnumConfigReader { | ||
inline def derived[A](using m: Mirror.SumOf[A]): EnumConfigReader[A] = { | ||
val values = summonCases[m.MirroredElemTypes, A] | ||
new EnumConfigReader[A] { | ||
def from(cur: ConfigCursor): ConfigReader.Result[A] = | ||
for { | ||
value <- cur.asString | ||
result <- | ||
ordinal[A](transformName, value) match { | ||
case Some(ord) => Right(values(ord)) | ||
case None => | ||
for { | ||
v <- cur.asConfigValue | ||
result <- | ||
cur.failed( | ||
CannotConvert(value, constValue[m.MirroredLabel], "The value is not a valid enum option.") | ||
) | ||
} yield result | ||
} | ||
} yield result | ||
} | ||
} | ||
|
||
inline def summonCases[T <: Tuple, A]: List[A] = | ||
inline erasedValue[T] match { | ||
case _: (h *: t) => | ||
(inline summonInline[Mirror.Of[h]] match { | ||
case m: Mirror.Singleton => | ||
widen[m.MirroredMonoType, A](m.fromProduct(EmptyTuple)) :: summonCases[t, A] | ||
case _ => error("Enums cannot include parameterized cases.") | ||
}) | ||
|
||
case _: EmptyTuple => Nil | ||
} | ||
|
||
inline def ordinal[A]( | ||
inline transformName: String => String, | ||
inline value: String | ||
)(using m: Mirror.SumOf[A]) = { | ||
val ord = Labels.transformed[m.MirroredElemLabels](transformName).indexOf(value) | ||
Option.when(ord >= 0)(ord) | ||
} | ||
} | ||
} | ||
|
||
object EnumConfigReaderDerivation { | ||
object Default extends EnumConfigReaderDerivation(ConfigFieldMapping(PascalCase, KebabCase)) | ||
} |
17 changes: 17 additions & 0 deletions
17
core/src/main/scala-3/pureconfig/generic/derivation/Labels.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 pureconfig.generic | ||
package derivation | ||
|
||
import scala.compiletime.{constValue, erasedValue, summonFrom, summonInline} | ||
import scala.deriving.Mirror | ||
|
||
object Labels { | ||
inline def transformed[T <: Tuple]( | ||
inline transform: String => String | ||
): List[String] = | ||
inline erasedValue[T] match { | ||
case _: (h *: t) => | ||
transform(constValue[h & String]) :: transformed[t](transform) | ||
|
||
case _: EmptyTuple => Nil | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
core/src/main/scala-3/pureconfig/generic/derivation/ProductConfigReaderDerivation.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,83 @@ | ||
package pureconfig | ||
package generic | ||
package derivation | ||
|
||
import scala.compiletime.{constValue, constValueTuple, erasedValue, summonFrom, summonInline} | ||
import scala.compiletime.ops.int._ | ||
import scala.deriving.Mirror | ||
import scala.util.chaining.* | ||
|
||
import pureconfig.error.{ConfigReaderFailures, ConvertFailure, KeyNotFound, UnknownKey, WrongSizeList} | ||
import pureconfig.generic.derivation.WidenType.widen | ||
|
||
trait ProductConfigReaderDerivation(fieldMapping: ConfigFieldMapping) { self: ConfigReaderDerivation => | ||
inline def derivedProduct[A](using m: Mirror.ProductOf[A]): ConfigReader[A] = | ||
inline erasedValue[A] match { | ||
case _: Tuple => | ||
new ConfigReader[A] { | ||
def from(cur: ConfigCursor): ConfigReader.Result[A] = | ||
for { | ||
listCur <- asList(cur) | ||
result <- readTuple[A & Tuple, 0](listCur.list, Nil) | ||
} yield result | ||
|
||
def asList(cur: ConfigCursor) = | ||
cur.asListCursor.flatMap { listCur => | ||
if (constValue[Tuple.Size[A & Tuple]] == listCur.size) | ||
Right(listCur) | ||
else | ||
listCur.failed( | ||
WrongSizeList(constValue[Tuple.Size[A & Tuple]], listCur.size) | ||
) | ||
} | ||
} | ||
|
||
case _ => | ||
new ConfigReader[A] { | ||
def from(cur: ConfigCursor): ConfigReader.Result[A] = | ||
for { | ||
objCur <- cur.asObjectCursor | ||
result <- | ||
Labels | ||
.transformed[m.MirroredElemLabels](fieldMapping) | ||
.pipe(labels => | ||
readTuple[m.MirroredElemTypes, 0]( | ||
labels.map(objCur.atKeyOrUndefined(_)), | ||
labels.map(KeyNotFound.forKeys(_, objCur.keys)) | ||
) | ||
) | ||
} yield m.fromProduct(result) | ||
} | ||
} | ||
|
||
inline def readTuple[T <: Tuple, N <: Int]( | ||
cursors: List[ConfigCursor], | ||
keyNotFound: List[KeyNotFound] | ||
): Either[ConfigReaderFailures, T] = | ||
inline erasedValue[T] match { | ||
case _: (h *: t) => | ||
val reader = summonConfigReader[h] | ||
val cursor = cursors(constValue[N]) | ||
val h = | ||
(reader.isInstanceOf[ReadsMissingKeys], cursor.isUndefined) match { | ||
case (true, true) | (_, false) => reader.from(cursor) | ||
case (false, true) => cursor.failed(keyNotFound(constValue[N])) | ||
} | ||
|
||
h -> readTuple[t, N + 1](cursors, keyNotFound) match { | ||
case (Right(h), Right(t)) => Right(widen[h *: t, T](h *: t)) | ||
case (Left(h), Left(t)) => Left(h ++ t) | ||
case (_, Left(failures)) => Left(failures) | ||
case (Left(failures), _) => Left(failures) | ||
} | ||
|
||
case _: EmptyTuple => | ||
Right(widen[EmptyTuple, T](EmptyTuple)) | ||
} | ||
|
||
inline def summonConfigReader[A] = | ||
summonFrom { | ||
case reader: ConfigReader[A] => reader | ||
case given Mirror.Of[A] => ConfigReader.derived[A] | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
core/src/main/scala-3/pureconfig/generic/derivation/WidenType.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,8 @@ | ||
package pureconfig.generic.derivation | ||
|
||
object WidenType { | ||
inline def widen[A, B](a: A): A & B = | ||
inline a match { | ||
case b: B => b | ||
} | ||
} |
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
Oops, something went wrong.