Skip to content

Commit 24c80dc

Browse files
committed
ConfigCompanion - move codecs to val in object, renames
1 parent 35f9d91 commit 24c80dc

File tree

2 files changed

+41
-33
lines changed

2 files changed

+41
-33
lines changed

hocon/src/main/scala/com/avsystem/commons/hocon/ConfigCompanion.scala

+34-31
Original file line numberDiff line numberDiff line change
@@ -2,68 +2,71 @@ package com.avsystem.commons
22
package hocon
33

44
import com.avsystem.commons.meta.MacroInstances
5-
import com.avsystem.commons.misc.ValueOf
6-
import com.avsystem.commons.serialization.{GenCodec, GenKeyCodec, GenObjectCodec, HasGenObjectCodecWithDeps}
75
import com.avsystem.commons.serialization.GenCodec.ReadFailure
6+
import com.avsystem.commons.serialization.{GenCodec, GenKeyCodec, GenObjectCodec}
87
import com.typesafe.config.{Config, ConfigFactory, ConfigObject}
98

109
import scala.concurrent.duration.*
1110

12-
trait CommonsHoconCodecs {
13-
implicit final val configCodec: GenCodec[Config] = GenCodec.nullable(
11+
trait HoconGenCodecs {
12+
implicit def configCodec: GenCodec[Config] = HoconGenCodecs.ConfigCodec
13+
implicit def finiteDurationCodec: GenCodec[FiniteDuration] = HoconGenCodecs.FiniteDurationCodec
14+
implicit def sizeInBytesCodec: GenCodec[SizeInBytes] = HoconGenCodecs.SizeInBytesCodec
15+
implicit def classKeyCodec: GenKeyCodec[Class[?]] = HoconGenCodecs.ClassKeyCodec
16+
implicit def classCodec: GenCodec[Class[?]] = HoconGenCodecs.ClassCodec
17+
}
18+
object HoconGenCodecs {
19+
implicit final val ConfigCodec: GenCodec[Config] = GenCodec.nullable(
1420
input =>
15-
input.readCustom(ConfigValueMarker).map {
21+
input.readCustom(ConfigValueMarker).fold(ConfigFactory.parseString(input.readSimple().readString())) {
1622
case obj: ConfigObject => obj.toConfig
1723
case v => throw new ReadFailure(s"expected a config OBJECT, got ${v.valueType}")
18-
}.getOrElse {
19-
ConfigFactory.parseString(input.readSimple().readString())
2024
},
2125
(output, value) =>
2226
if (!output.writeCustom(ConfigValueMarker, value.root)) {
2327
output.writeSimple().writeString(value.root.render)
2428
},
2529
)
2630

27-
implicit final val finiteDurationCodec: GenCodec[FiniteDuration] = GenCodec.nullable(
31+
implicit final val FiniteDurationCodec: GenCodec[FiniteDuration] = GenCodec.nullable(
2832
input => input.readCustom(DurationMarker).fold(input.readSimple().readLong())(_.toMillis).millis,
2933
(output, value) => output.writeSimple().writeLong(value.toMillis),
3034
)
3135

32-
implicit final val sizeInBytesCodec: GenCodec[SizeInBytes] = GenCodec.nonNull(
36+
implicit final val SizeInBytesCodec: GenCodec[SizeInBytes] = GenCodec.nonNull(
3337
input => SizeInBytes(input.readCustom(SizeInBytesMarker).getOrElse(input.readSimple().readLong())),
3438
(output, value) => output.writeSimple().writeLong(value.bytes),
3539
)
3640

37-
implicit final val classKeyCodec: GenKeyCodec[Class[?]] =
41+
implicit final val ClassKeyCodec: GenKeyCodec[Class[?]] =
3842
GenKeyCodec.create(Class.forName, _.getName)
3943

40-
implicit final val classCodec: GenCodec[Class[?]] =
44+
implicit final val ClassCodec: GenCodec[Class[?]] =
4145
GenCodec.nullableString(Class.forName, _.getName)
4246
}
43-
object CommonsHoconCodecs extends CommonsHoconCodecs
47+
48+
object DefaultHoconGenCodecs extends HoconGenCodecs
49+
50+
trait ConfigObjectCodec[T] {
51+
def objectCodec: GenObjectCodec[T]
52+
}
53+
54+
abstract class AbstractConfigCompanion[Implicits <: HoconGenCodecs, T](
55+
implicits: Implicits
56+
)(implicit instances: MacroInstances[Implicits, ConfigObjectCodec[T]]
57+
) {
58+
implicit lazy val codec: GenCodec[T] = instances(implicits, this).objectCodec
59+
60+
final def read(config: Config): T = HoconInput.read[T](config)
61+
}
4462

4563
/**
4664
* Base class for companion objects of configuration case classes and sealed traits
4765
* (typically deserialized from HOCON files).
4866
*
49-
* [[ConfigCompanion]] is equivalent to [[com.avsystem.commons.serialization.HasGenCodec HasGenCodec]]
50-
* except that it automatically imports codecs from [[CommonsHoconCodecs]] - codecs for third party types often used
67+
* [[DefaultConfigCompanion]] is equivalent to [[com.avsystem.commons.serialization.HasGenCodec HasGenCodec]]
68+
* except that it automatically imports codecs from [[HoconGenCodecs]] - codecs for third party types often used
5169
* in configuration.
5270
*/
53-
abstract class ConfigCompanion[T](implicit
54-
macroCodec: MacroInstances[CommonsHoconCodecs.type, () => GenObjectCodec[T]],
55-
) extends HasGenObjectCodecWithDeps[CommonsHoconCodecs.type, T] {
56-
final def read(config: Config): T = HoconInput.read[T](config)
57-
}
58-
59-
/**
60-
* A version of [[ConfigCompanion]] which injects additional implicits into macro materialization.
61-
* Implicits are imported from an object specified with type parameter `D`.
62-
* It must be a singleton object type, i.e. `SomeObject.type`.
63-
*/
64-
abstract class ConfigCompanionWithDeps[T, D <: CommonsHoconCodecs](implicit
65-
deps: ValueOf[D],
66-
macroCodec: MacroInstances[D, () => GenObjectCodec[T]],
67-
) extends HasGenObjectCodecWithDeps[D, T] {
68-
final def read(config: Config): T = HoconInput.read[T](config)
69-
}
71+
abstract class DefaultConfigCompanion[T](implicit macroCodec: MacroInstances[HoconGenCodecs, ConfigObjectCodec[T]])
72+
extends AbstractConfigCompanion[HoconGenCodecs, T](DefaultHoconGenCodecs)

hocon/src/test/scala/com/avsystem/commons/hocon/HoconInputTest.scala

+7-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ object HoconInputTest {
1414
fileSize: SizeInBytes,
1515
embeddedConfig: Config,
1616
clazz: Class[?],
17+
clazzMap: Map[Class[?], String],
1718
)
18-
object CustomCodecsClass extends ConfigCompanion[CustomCodecsClass]
19+
object CustomCodecsClass extends DefaultConfigCompanion[CustomCodecsClass]
1920
}
2021

2122
class HoconInputTest extends GenCodecRoundtripTest {
@@ -79,14 +80,18 @@ class HoconInputTest extends GenCodecRoundtripTest {
7980
| embeddedConfig {
8081
| something = "abc"
8182
| }
82-
| clazz = "com.avsystem.commons.hocon.HoconInputTest"
83+
| clazz = "com.avsystem.commons.hocon.HoconInputTest",
84+
| clazzMap {
85+
| "com.avsystem.commons.hocon.HoconInputTest" = "abc"
86+
| }
8387
|}""".stripMargin
8488
)
8589
val expected = CustomCodecsClass(
8690
duration = 1.minute,
8791
fileSize = SizeInBytes.`1KiB`,
8892
embeddedConfig = ConfigFactory.parseMap(JMap("something" -> "abc")),
8993
clazz = classOf[HoconInputTest],
94+
clazzMap = Map(classOf[HoconInputTest] -> "abc")
9095
)
9196
assert(CustomCodecsClass.read(config) == expected)
9297
}

0 commit comments

Comments
 (0)