Skip to content

Commit

Permalink
Merge e9f72d3 into eb1016f
Browse files Browse the repository at this point in the history
  • Loading branch information
ruippeixotog committed Feb 28, 2021
2 parents eb1016f + e9f72d3 commit 01d9e0e
Show file tree
Hide file tree
Showing 49 changed files with 118 additions and 140 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ jobs:
fail-fast: false
matrix:
jdk: [adopt@1.8]
scala: ['2.11', '2.12', '2.13', '3.0']
scala: ['2.12', '2.13', '3.0']
include:
- scala: '2.11'
scala-version: 2.11.12
- scala: '2.12'
scala-version: 2.12.12
- scala: '2.13'
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ certain type. In other words, you define **what** to load and PureConfig provide

## Quick Start

To use PureConfig in an existing SBT project with Scala 2.11 or a later version, add the following dependency to your
To use PureConfig in an existing SBT project with Scala 2.12 or a later version, add the following dependency to your
`build.sbt`:

```scala
Expand Down
19 changes: 2 additions & 17 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ lazy val commonSettings = Seq(
)

// add support for Scala version ranges such as "scala-2.12+" or "scala-2.13-" in source folders (single version folders
// such as "scala-2.11" are natively supported by SBT).
// such as "scala-2.12" are natively supported by SBT).
def crossVersionSharedSources(unmanagedSrcs: SettingKey[Seq[File]]) = {
unmanagedSrcs ++= {
val versionNumber = CrossVersion.partialVersion(scalaVersion.value)
val expectedVersions = Seq(scala211, scala212, scala213, scala30).flatMap(CrossVersion.partialVersion)
val expectedVersions = Seq(scala212, scala213, scala30).flatMap(CrossVersion.partialVersion)
expectedVersions.flatMap { case v @ (major, minor) =>
List(
if (versionNumber.exists(_ <= v)) unmanagedSrcs.value.map { dir => new File(dir.getPath + s"-$major.$minor-") }
Expand All @@ -122,21 +122,6 @@ def crossVersionSharedSources(unmanagedSrcs: SettingKey[Seq[File]]) = {
}

lazy val lintFlags = forScalaVersions {
case (2, 11) =>
List(
"-encoding",
"UTF-8", // arg for -encoding
"-feature",
"-unchecked",
"-deprecation",
"-Xlint",
"-Xfatal-warnings",
"-Yno-adapted-args",
"-Ywarn-unused-import",
"-Ywarn-dead-code",
"-Ywarn-numeric-widen"
)

case (2, 12) =>
List(
"-encoding",
Expand Down
2 changes: 1 addition & 1 deletion bundle/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import Dependencies.Version._

name := "pureconfig"

crossScalaVersions := Seq(scala211, scala212, scala213)
crossScalaVersions := Seq(scala212, scala213)
2 changes: 1 addition & 1 deletion bundle/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ certain type. In other words, you define **what** to load and PureConfig provide

## Quick Start

To use PureConfig in an existing SBT project with Scala 2.11 or a later version, add the following dependency to your
To use PureConfig in an existing SBT project with Scala 2.12 or a later version, add the following dependency to your
`build.sbt`:

```scala
Expand Down
2 changes: 1 addition & 1 deletion core/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Dependencies.Version._

name := "pureconfig-core"

crossScalaVersions := Seq(scala211, scala212, scala213, scala30)
crossScalaVersions := Seq(scala212, scala213, scala30)

libraryDependencies += Dependencies.typesafeConfig

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait ProductReaders {
if (reader.isInstanceOf[ReadsMissingKeys])
reader.from(cursor.atKeyOrUndefined(key))
else
cursor.atKey(key).right.flatMap(reader.from))(_(_))
cursor.atKey(key).flatMap(reader.from))(_(_))

/**
* Builds a `ConfigReader` for an object created from the value of 1 key.
Expand All @@ -26,7 +26,7 @@ trait ProductReaders {
readerA0: ConfigReader[A0]
): ConfigReader[B] = new ConfigReader[B] {
def from(cur: ConfigCursor): ConfigReader.Result[B] =
cur.asObjectCursor.right.flatMap { objCur =>
cur.asObjectCursor.flatMap { objCur =>
val a0Result: ConfigReader.Result[A0 => B] = Right(f)
val a1Result = combineReaderResult(a0Result, readerA0, keyA0, objCur)
a1Result
Expand All @@ -45,7 +45,7 @@ trait ProductReaders {
[#readerA0: ConfigReader[A0]#]
): ConfigReader[B] = new ConfigReader[B] {
def from(cur: ConfigCursor): ConfigReader.Result[B] =
cur.asObjectCursor.right.flatMap { objCur =>
cur.asObjectCursor.flatMap { objCur =>
val a##0Result: ConfigReader.Result[[#A0# => ] => B] = Right(f.curried)
[#val a1Result = combineReaderResult(a0Result, readerA0, keyA0, objCur)#
]
Expand Down
12 changes: 6 additions & 6 deletions core/src/main/scala/pureconfig/BasicReaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ trait PrimitiveReaders {
case v => v.toDouble
})

cur.asString.right.flatMap(s => cur.scopeFailure(asStringReader(s))).left.flatMap(_ => cur.asDouble)
cur.asString.flatMap(s => cur.scopeFailure(asStringReader(s))).left.flatMap(_ => cur.asDouble)
})

implicit val floatConfigReader: ConfigReader[Float] = ConfigReader.fromCursor({ cur =>
Expand All @@ -49,7 +49,7 @@ trait PrimitiveReaders {
case v => v.toFloat
})

cur.asString.right.flatMap(s => cur.scopeFailure(asStringReader(s))).left.flatMap(_ => cur.asFloat)
cur.asString.flatMap(s => cur.scopeFailure(asStringReader(s))).left.flatMap(_ => cur.asFloat)
})

implicit val intConfigReader: ConfigReader[Int] = ConfigReader.fromCursor(_.asInt)
Expand Down Expand Up @@ -125,7 +125,7 @@ trait DurationReaders {

implicit val finiteDurationConfigReader: ConfigReader[FiniteDuration] = {
val fromString: String => Either[FailureReason, FiniteDuration] = { string =>
DurationUtils.fromString(string).right.flatMap {
DurationUtils.fromString(string).flatMap {
case d: FiniteDuration => Right(d)
case _ =>
Left(
Expand Down Expand Up @@ -163,16 +163,16 @@ trait NumericReaders {
trait TypesafeConfigReaders {

implicit val configConfigReader: ConfigReader[Config] =
ConfigReader.fromCursor(_.asObjectCursor.right.map(_.objValue.toConfig))
ConfigReader.fromCursor(_.asObjectCursor.map(_.objValue.toConfig))

implicit val configObjectConfigReader: ConfigReader[ConfigObject] =
ConfigReader.fromCursor(_.asObjectCursor.right.map(_.objValue))
ConfigReader.fromCursor(_.asObjectCursor.map(_.objValue))

implicit val configValueConfigReader: ConfigReader[ConfigValue] =
ConfigReader.fromCursor(_.asConfigValue)

implicit val configListConfigReader: ConfigReader[ConfigList] =
ConfigReader.fromCursor(_.asListCursor.right.map(_.listValue))
ConfigReader.fromCursor(_.asListCursor.map(_.listValue))

// TODO: improve error handling by copying the parsing logic from Typesafe and making it use PureConfig Results
// (see PeriodUtils and DurationUtils)
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/scala/pureconfig/CollectionReaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ trait CollectionReaders {
new ConfigReader[Option[A]] with ReadsMissingKeys {
override def from(cur: ConfigCursor): ConfigReader.Result[Option[A]] = {
if (cur.isUndefined || cur.isNull) Right(None)
else conv.value.from(cur).right.map(Some(_))
else conv.value.from(cur).map(Some(_))
}
}

Expand All @@ -30,7 +30,7 @@ trait CollectionReaders {
new ConfigReader[F[A]] {

override def from(cur: ConfigCursor): ConfigReader.Result[F[A]] = {
cur.fluent.mapList { valueCur => configConvert.value.from(valueCur) }.right.map { coll =>
cur.fluent.mapList { valueCur => configConvert.value.from(valueCur) }.map { coll =>
val builder = cbf.newBuilder()
(builder ++= coll).result()
}
Expand All @@ -47,7 +47,7 @@ trait CollectionReaders {
implicit def arrayReader[A: ClassTag](implicit reader: Derivation[ConfigReader[A]]): ConfigReader[Array[A]] =
new ConfigReader[Array[A]] {
override def from(cur: ConfigCursor): ConfigReader.Result[Array[A]] =
cur.fluent.mapList(reader.value.from).right.map(_.toArray)
cur.fluent.mapList(reader.value.from).map(_.toArray)
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/pureconfig/ConfigConvert.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ object ConfigConvert extends ConvertHelpers {
def viaNonEmptyString[A](fromF: String => Either[FailureReason, A], toF: A => String)(implicit
ct: ClassTag[A]
): ConfigConvert[A] = {
viaString[A](string => ensureNonEmpty(ct)(string).right.flatMap(s => fromF(s)), toF)
viaString[A](string => ensureNonEmpty(ct)(string).flatMap(s => fromF(s)), toF)
}

def viaNonEmptyStringTry[A: ClassTag](fromF: String => Try[A], toF: A => String): ConfigConvert[A] = {
Expand Down
20 changes: 10 additions & 10 deletions core/src/main/scala/pureconfig/ConfigCursor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -173,31 +173,31 @@ sealed trait ConfigCursor {
* otherwise.
*/
def asListCursor: ConfigReader.Result[ConfigListCursor] =
castOrFail(LIST, v => Right(v.asInstanceOf[ConfigList])).right.map(ConfigListCursor(_, pathElems))
castOrFail(LIST, v => Right(v.asInstanceOf[ConfigList])).map(ConfigListCursor(_, pathElems))

/** Casts this cursor to a list of cursors.
*
* @return a `Right` with the list pointed to by this cursor if the cast can be done, `Left` with a list of failures
* otherwise.
*/
def asList: ConfigReader.Result[List[ConfigCursor]] =
asListCursor.right.map(_.list)
asListCursor.map(_.list)

/** Casts this cursor to a `ConfigObjectCursor`.
*
* @return a `Right` with this cursor as an object cursor if it points to an object, `Left` with a list of failures
* otherwise.
*/
def asObjectCursor: ConfigReader.Result[ConfigObjectCursor] =
castOrFail(OBJECT, v => Right(v.asInstanceOf[ConfigObject])).right.map(ConfigObjectCursor(_, pathElems))
castOrFail(OBJECT, v => Right(v.asInstanceOf[ConfigObject])).map(ConfigObjectCursor(_, pathElems))

/** Casts this cursor to a map from config keys to cursors.
*
* @return a `Right` with the map pointed to by this cursor if the cast can be done, `Left` with a list of failures
* otherwise.
*/
def asMap: ConfigReader.Result[Map[String, ConfigCursor]] =
asObjectCursor.right.map(_.map)
asObjectCursor.map(_.map)

/** Returns a cursor to the config at the path composed of given path segments.
*
Expand All @@ -215,15 +215,15 @@ sealed trait ConfigCursor {
*/
@deprecated("Use `asListCursor` and/or `asObjectCursor` instead", "0.10.1")
def asCollectionCursor: ConfigReader.Result[Either[ConfigListCursor, ConfigObjectCursor]] = {
asConfigValue.right.flatMap { value =>
val listAtLeft = asListCursor.right.map(Left.apply)
lazy val mapAtRight = asObjectCursor.right.map(Right.apply)
asConfigValue.flatMap { value =>
val listAtLeft = asListCursor.map(Left.apply)
lazy val mapAtRight = asObjectCursor.map(Right.apply)
listAtLeft.left.flatMap(_ => mapAtRight).left.flatMap(_ => failed(WrongType(value.valueType, Set(LIST, OBJECT))))
}
}

def fluent: FluentConfigCursor =
FluentConfigCursor(asConfigValue.right.map(_ => this))
FluentConfigCursor(asConfigValue.map(_ => this))

/** Returns a failed `ConfigReader` result resulting from scoping a `FailureReason` into the context of this cursor.
*
Expand Down Expand Up @@ -265,8 +265,8 @@ sealed trait ConfigCursor {
cast: ConfigValue => Either[FailureReason, A]
): ConfigReader.Result[A] = {

asConfigValue.right.flatMap { value =>
scopeFailure(ConfigCursor.transform(value, expectedType).right.flatMap(cast))
asConfigValue.flatMap { value =>
scopeFailure(ConfigCursor.transform(value, expectedType).flatMap(cast))
}
}
}
Expand Down
13 changes: 6 additions & 7 deletions core/src/main/scala/pureconfig/ConfigReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ trait ConfigReader[A] {
* @return a `ConfigReader` returning the results of this reader mapped by `f`.
*/
def map[B](f: A => B): ConfigReader[B] =
fromCursor[B] { cur => from(cur).right.flatMap { v => cur.scopeFailure(toResult(f)(v)) } }
fromCursor[B] { cur => from(cur).flatMap { v => cur.scopeFailure(toResult(f)(v)) } }

/** Maps a function that can possibly fail over the results of this reader.
*
Expand All @@ -48,7 +48,7 @@ trait ConfigReader[A] {
* as a success or failure.
*/
def emap[B](f: A => Either[FailureReason, B]): ConfigReader[B] =
fromCursor[B] { cur => from(cur).right.flatMap { v => cur.scopeFailure(f(v)) } }
fromCursor[B] { cur => from(cur).flatMap { v => cur.scopeFailure(f(v)) } }

/** Monadically bind a function over the results of this reader.
*
Expand All @@ -57,7 +57,7 @@ trait ConfigReader[A] {
* @return a `ConfigReader` returning the results of this reader bound by `f`.
*/
def flatMap[B](f: A => ConfigReader[B]): ConfigReader[B] =
fromCursor[B] { cur => from(cur).right.flatMap(f(_).from(cur)) }
fromCursor[B] { cur => from(cur).flatMap(f(_).from(cur)) }

/** Combines this reader with another, returning both results as a pair.
*
Expand Down Expand Up @@ -131,8 +131,7 @@ object ConfigReader extends BasicReaders with CollectionReaders with ProductRead
case (Left(err), Right(_)) => Left(err)
case (Right(_), Left(err)) => Left(err)
case (Left(errs), Left(err)) => Left(errs ++ err)
}.right
.map(_.result())
}.map(_.result())
}

/** Merges two `Result`s using a given function.
Expand Down Expand Up @@ -172,7 +171,7 @@ object ConfigReader extends BasicReaders with CollectionReaders with ProductRead
* @return a `ConfigReader` for reading objects of type `A` using `fromF`.
*/
def fromFunction[A](fromF: ConfigValue => ConfigReader.Result[A]) =
fromCursor(_.asConfigValue.right.flatMap(fromF))
fromCursor(_.asConfigValue.flatMap(fromF))

def fromString[A](fromF: String => Either[FailureReason, A]): ConfigReader[A] =
ConfigReader.fromCursor(_.asString).emap(fromF)
Expand All @@ -186,7 +185,7 @@ object ConfigReader extends BasicReaders with CollectionReaders with ProductRead
}

def fromNonEmptyString[A](fromF: String => Either[FailureReason, A])(implicit ct: ClassTag[A]): ConfigReader[A] = {
fromString(string => ensureNonEmpty(ct)(string).right.flatMap(s => fromF(s)))
fromString(string => ensureNonEmpty(ct)(string).flatMap(s => fromF(s)))
}

def fromNonEmptyStringTry[A](fromF: String => Try[A])(implicit ct: ClassTag[A]): ConfigReader[A] = {
Expand Down
12 changes: 6 additions & 6 deletions core/src/main/scala/pureconfig/ConfigSource.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ trait ConfigSource {
* @return a cursor for a `ConfigValue` retrieved from this source.
*/
def cursor(): Result[ConfigCursor] =
value().right.map(ConfigCursor(_, Nil))
value().map(ConfigCursor(_, Nil))

/** Returns a fluent cursor for a `ConfigValue` retrieved from this source.
*
Expand All @@ -58,7 +58,7 @@ trait ConfigSource {
* `A` from this source, a `Failure` with details on why it isn't possible otherwise
*/
final def load[A](implicit reader: Derivation[ConfigReader[A]]): Result[A] =
cursor().right.flatMap(reader.value.from)
cursor().flatMap(reader.value.from)

/** Loads a configuration of type `A` from this source. If it is not possible to create an
* instance of `A`, this method throws a `ConfigReaderException`.
Expand All @@ -83,11 +83,11 @@ trait ConfigSource {
final class ConfigObjectSource private (getConf: () => Result[Config]) extends ConfigSource {

def value(): Result[ConfigObject] =
config().right.flatMap(_.resolveSafe()).right.map(_.root)
config().flatMap(_.resolveSafe()).map(_.root)

// Avoids unnecessary cast on `ConfigCursor#asObjectCursor`.
override def cursor(): Result[ConfigCursor] =
value().right.map(ConfigObjectCursor(_, Nil))
value().map(ConfigObjectCursor(_, Nil))

/** Reads a `Config` from this config source. The returned config is usually unresolved, unless
* the source forces it otherwise.
Expand Down Expand Up @@ -179,7 +179,7 @@ object ConfigSource {
* custom application config source.
*/
def default(appSource: ConfigObjectSource): ConfigObjectSource =
ConfigObjectSource(appSource.config().right.flatMap(ConfigFactoryWrapper.load))
ConfigObjectSource(appSource.config().flatMap(ConfigFactoryWrapper.load))

/** A config source that always provides empty configs.
*/
Expand Down Expand Up @@ -301,7 +301,7 @@ object ConfigSource {
*/
private[pureconfig] def fromCursor(cur: FluentConfigCursor): ConfigSource =
new ConfigSource {
def value(): Result[ConfigValue] = cur.cursor.right.flatMap(_.asConfigValue)
def value(): Result[ConfigValue] = cur.cursor.flatMap(_.asConfigValue)
override def cursor() = cur.cursor
override def fluentCursor() = cur
}
Expand Down

0 comments on commit 01d9e0e

Please sign in to comment.