diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml
index 5a8ebc3..b5ca820 100644
--- a/.github/workflows/format.yml
+++ b/.github/workflows/format.yml
@@ -23,4 +23,4 @@ jobs:
- name: Check project is formatted
uses: jrouly/scalafmt-native-action@v1
with:
- version: '2.7.5'
+ version: '3.4.3'
diff --git a/.scalafmt.conf b/.scalafmt.conf
index d141fdb..d17e2d0 100644
--- a/.scalafmt.conf
+++ b/.scalafmt.conf
@@ -1,14 +1,17 @@
-version = 2.7.5
+version = 3.4.3
+runner.dialect = scala213
preset = default
align.preset = most
maxColumn = 120
project.git = true
-align.tokens.add = [
+docstrings.style = AsteriskSpace
+align.tokens."+" = [
{code = ":=", owner = "Term.ApplyInfix"}
]
rewrite.rules = [RedundantBraces, RedundantParens]
-# TODO update scalafmt for Scala 3 support
-project.excludeFilters = [
- "src/main/scala-3/net/ceedubs/ficus/util/EnumerationUtil.scala"
-]
+fileOverride {
+ "glob:**/src/main/scala-3/**" {
+ runner.dialect = scala3
+ }
+}
diff --git a/src/main/scala/net/ceedubs/ficus/readers/DurationReaders.scala b/src/main/scala/net/ceedubs/ficus/readers/DurationReaders.scala
index 7b12d00..ce65ec8 100644
--- a/src/main/scala/net/ceedubs/ficus/readers/DurationReaders.scala
+++ b/src/main/scala/net/ceedubs/ficus/readers/DurationReaders.scala
@@ -8,9 +8,9 @@ import scala.util.Try
trait DurationReaders {
/** A reader for for a scala.concurrent.duration.FiniteDuration. This reader should be able to read any valid duration
- * format as defined by the HOCON spec.
- * For example, it can read "15 minutes" or "1 day".
- */
+ * format as defined by the HOCON spec. For
+ * example, it can read "15 minutes" or "1 day".
+ */
implicit def finiteDurationReader: ValueReader[FiniteDuration] = new ValueReader[FiniteDuration] {
def read(config: Config, path: String): FiniteDuration = {
val nanos = config.getDuration(path, NANOSECONDS)
@@ -18,12 +18,13 @@ trait DurationReaders {
}
}
- /** A reader for for a scala.concurrent.duration.Duration. This reader should be able to read any valid duration format
- * as defined by the HOCON spec and positive
- * and negative infinite values supported by Duration's apply method.
- * For example, it can read "15 minutes", "1 day", "-Inf", or "PlusInf".
- */
+ /** A reader for for a scala.concurrent.duration.Duration. This reader should be able to read any valid duration
+ * format as defined by the HOCON spec and
+ * positive and negative infinite values supported by Duration's apply method. For
+ * example, it can read "15 minutes", "1 day", "-Inf", or "PlusInf".
+ */
implicit def durationReader: ValueReader[Duration] = new ValueReader[Duration] {
def read(config: Config, path: String): Duration =
(Try {
diff --git a/src/main/scala/net/ceedubs/ficus/readers/InetSocketAddressReaders.scala b/src/main/scala/net/ceedubs/ficus/readers/InetSocketAddressReaders.scala
index 9775ddc..c43251d 100644
--- a/src/main/scala/net/ceedubs/ficus/readers/InetSocketAddressReaders.scala
+++ b/src/main/scala/net/ceedubs/ficus/readers/InetSocketAddressReaders.scala
@@ -18,17 +18,19 @@ trait InetSocketAddressReaders {
implicit val inetSocketAddressListReader: ValueReader[List[InetSocketAddress]] =
new ValueReader[List[InetSocketAddress]] {
def read(config: Config, path: String): List[InetSocketAddress] =
- try config
- .getString(path)
- .split(", *")
- .toList
- .map(parseHostAndPort)
- .partition(_.isEmpty) match {
- case (errors, ok) if errors.isEmpty =>
- ok.flatten
- case _ =>
- throw new IllegalArgumentException("Cannot parse string into hosts and ports")
- } catch {
+ try
+ config
+ .getString(path)
+ .split(", *")
+ .toList
+ .map(parseHostAndPort)
+ .partition(_.isEmpty) match {
+ case (errors, ok) if errors.isEmpty =>
+ ok.flatten
+ case _ =>
+ throw new IllegalArgumentException("Cannot parse string into hosts and ports")
+ }
+ catch {
case e: Exception =>
throw new ConfigException.WrongType(config.origin(), path, "java.net.InetSocketAddress", "String", e)
}
@@ -36,8 +38,9 @@ trait InetSocketAddressReaders {
implicit val inetSocketAddressReader: ValueReader[InetSocketAddress] = new ValueReader[InetSocketAddress] {
def read(config: Config, path: String): InetSocketAddress =
- try parseHostAndPort(config.getString(path))
- .getOrElse(throw new IllegalArgumentException("Cannot parse string into host and port"))
+ try
+ parseHostAndPort(config.getString(path))
+ .getOrElse(throw new IllegalArgumentException("Cannot parse string into host and port"))
catch {
case e: Exception =>
throw new ConfigException.WrongType(config.origin(), path, "java.net.InetSocketAddress", "String", e)
diff --git a/src/main/scala/net/ceedubs/ficus/readers/NameMapper.scala b/src/main/scala/net/ceedubs/ficus/readers/NameMapper.scala
index 1be1a4c..692d1d1 100644
--- a/src/main/scala/net/ceedubs/ficus/readers/NameMapper.scala
+++ b/src/main/scala/net/ceedubs/ficus/readers/NameMapper.scala
@@ -1,31 +1,34 @@
package net.ceedubs.ficus.readers
-/** Defines an object that knows to map between names as they found in the code
- * to those who should be defined in the configuration
- */
+/** Defines an object that knows to map between names as they found in the code to those who should be defined in the
+ * configuration
+ */
trait NameMapper {
/** Maps between the name in the code to name in configuration
- * @param name The name as found in the code
- */
+ * @param name
+ * The name as found in the code
+ */
def map(name: String): String
}
/** Helper object to get the current name mapper
- */
+ */
object NameMapper {
/** Gets the name mapper from the implicit scope
- * @param nameMapper The name mapper from the implicit scope, or the default name mapper if not found
- * @return The name mapper to be used in current implicit scope
- */
+ * @param nameMapper
+ * The name mapper from the implicit scope, or the default name mapper if not found
+ * @return
+ * The name mapper to be used in current implicit scope
+ */
def apply()(implicit nameMapper: NameMapper = DefaultNameMapper): NameMapper = nameMapper
}
/** Default implementation for name mapper, names in code equivalent to names in configuration
- */
+ */
case object DefaultNameMapper extends NameMapper {
override def map(name: String): String = name
diff --git a/src/main/scala/net/ceedubs/ficus/readers/ValueReader.scala b/src/main/scala/net/ceedubs/ficus/readers/ValueReader.scala
index a85f306..c25611c 100644
--- a/src/main/scala/net/ceedubs/ficus/readers/ValueReader.scala
+++ b/src/main/scala/net/ceedubs/ficus/readers/ValueReader.scala
@@ -9,8 +9,8 @@ trait ValueReader[A] { self =>
def read(config: Config, path: String): A
/** Turns a ValueReader[A] into a ValueReader[B] by applying the provided transformation `f` on the item of type A
- * that is read from config
- */
+ * that is read from config
+ */
def map[B](f: A => B): ValueReader[B] = new ValueReader[B] {
def read(config: Config, path: String): B = f(self.read(config, path))
}
@@ -19,36 +19,35 @@ trait ValueReader[A] { self =>
object ValueReader {
implicit def generatedReader[A](implicit generated: Generated[ValueReader[A]]): ValueReader[A] = generated.value
- /** Returns the implicit ValueReader[A] in scope.
- * `ValueReader[A]` is equivalent to `implicitly[ValueReader[A]]`
- */
+ /** Returns the implicit ValueReader[A] in scope. `ValueReader[A]` is equivalent to `implicitly[ValueReader[A]]`
+ */
def apply[A](implicit reader: ValueReader[A]): ValueReader[A] = reader
/** ValueReader that receives a Config whose root is the path being read.
- *
- * This is generally the most concise way to implement a ValueReader that doesn't depend on the path of the value
- * being read.
- *
- * For example to read a `case class FooBar(foo: Foo, bar: Bar)`, instead of
- * {{{
- * new ValueReader[FooBar] {
- * def read(config: Config, path: String): FooBar = {
- * val localizedConfig = config.getConfig(path)
- * FooBar(
- * foo = localizedConfig.as[Foo]("foo"),
- * bar = localizedConfig.as[Bar]("bar"))
- * }
- * }
- * }}}
- * you could do
- * {{{
- * ValueReader.relative[FooBar] { config =>
- * FooBar(
- * foo = config.as[Foo]("foo"),
- * bar = config.as[Bar]("bar))
- * }
- * }}}
- */
+ *
+ * This is generally the most concise way to implement a ValueReader that doesn't depend on the path of the value
+ * being read.
+ *
+ * For example to read a `case class FooBar(foo: Foo, bar: Bar)`, instead of
+ * {{{
+ * new ValueReader[FooBar] {
+ * def read(config: Config, path: String): FooBar = {
+ * val localizedConfig = config.getConfig(path)
+ * FooBar(
+ * foo = localizedConfig.as[Foo]("foo"),
+ * bar = localizedConfig.as[Bar]("bar"))
+ * }
+ * }
+ * }}}
+ * you could do
+ * {{{
+ * ValueReader.relative[FooBar] { config =>
+ * FooBar(
+ * foo = config.as[Foo]("foo"),
+ * bar = config.as[Bar]("bar))
+ * }
+ * }}}
+ */
def relative[A](f: Config => A): ValueReader[A] = new ValueReader[A] {
def read(config: Config, path: String): A = f(config.getConfig(path))
}
diff --git a/src/main/scala/net/ceedubs/ficus/readers/namemappers/HyphenNameMapper.scala b/src/main/scala/net/ceedubs/ficus/readers/namemappers/HyphenNameMapper.scala
index ee83940..efdad64 100644
--- a/src/main/scala/net/ceedubs/ficus/readers/namemappers/HyphenNameMapper.scala
+++ b/src/main/scala/net/ceedubs/ficus/readers/namemappers/HyphenNameMapper.scala
@@ -6,6 +6,6 @@ object HyphenNameMapper extends NameMapper {
private lazy val r = "((?<=[a-z0-9])[A-Z]|(?<=[a-zA-Z])[0-9]|(?!^)[A-Z](?=[a-z]))".r
/** Maps from a camelCasedName to a hyphenated-name
- */
+ */
override def map(name: String): String = r.replaceAllIn(name, m => s"-${m.group(1)}").toLowerCase
}
diff --git a/src/main/scala/net/ceedubs/ficus/readers/namemappers/HyphenNameMapperNoDigits.scala b/src/main/scala/net/ceedubs/ficus/readers/namemappers/HyphenNameMapperNoDigits.scala
index 2823c61..c270fab 100644
--- a/src/main/scala/net/ceedubs/ficus/readers/namemappers/HyphenNameMapperNoDigits.scala
+++ b/src/main/scala/net/ceedubs/ficus/readers/namemappers/HyphenNameMapperNoDigits.scala
@@ -6,6 +6,6 @@ object HyphenNameMapperNoDigits extends NameMapper {
private lazy val r = "((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))".r
/** Maps from a camelCasedName to a hyphenated-name
- */
+ */
override def map(name: String): String = r.replaceAllIn(name, m => s"-${m.group(1)}").toLowerCase
}