Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add safe ZIO methods builders of ConfigProvider #1398

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ lazy val scala212projects = Seq[ProjectReference](
zioConfigCatsJVM,
zioConfigRefinedJVM,
zioConfigMagnoliaJVM,
zioConfigTypesafeMagnoliaTestsJVM,
zioConfigZioAwsJVM,
zioConfigXmlJVM,
examplesJVM
Expand Down Expand Up @@ -409,7 +410,7 @@ lazy val zioConfigTypesafeMagnoliaTests = crossProject(JVMPlatform)
),
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework"))
)
.dependsOn(zioConfig % "compile->compile;test->test", zioConfigTypesafe, zioConfigMagnolia)
.dependsOn(zioConfig % "compile->compile;test->test", zioConfigTypesafe, zioConfigMagnolia, zioConfigDerivation)
lazy val zioConfigTypesafeMagnoliaTestsJVM = zioConfigTypesafeMagnoliaTests.jvm

lazy val docs = project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,26 @@ package zio.config.syntax

import zio.Config.Error.{And, InvalidData, MissingData, Or, SourceUnavailable, Unsupported}
import zio.config.TupleConversion
import zio.{Chunk, Config, ConfigProvider, IO}
import zio.config.syntax.ConfigSyntax.ConfigProviderZIO
import zio.{Chunk, Config, ConfigProvider, IO, Task}

import java.util.UUID
import scala.util.control.NonFatal

// Backward compatible approach to minimise the client changes
final case class Read[A](config: Config[A], configProvider: ConfigProvider)

final case class ReadZIO[A](config: Config[A], configProvider: ConfigProviderZIO)

object ConfigSyntax {
type ConfigProviderZIO = IO[Config.Error, ConfigProvider]

implicit class ConfigProviderZIOOps(buildConfigProvider: Task[ConfigProvider]) {
def toConfigProviderZIO: ConfigProviderZIO =
buildConfigProvider.mapError(throwable => Config.Error.Unsupported(message = throwable.toString))
}
}

// To be moved to ZIO ?
// Or may be zio-config can be considered as an extension to ZIO
trait ConfigSyntax {
Expand All @@ -18,6 +30,9 @@ trait ConfigSyntax {
final def read[A](reader: Read[A]): IO[Config.Error, A] =
reader.configProvider.load(reader.config)

final def read[A](reader: ReadZIO[A]): IO[Config.Error, A] =
reader.configProvider.flatMap(_.load(reader.config))

implicit class ConfigErrorOps(error: Config.Error) {
self =>

Expand Down Expand Up @@ -186,6 +201,11 @@ trait ConfigSyntax {
// Example: read(config from ConfigProvider.fromMap(""))
def from(configProvider: ConfigProvider): Read[A] =
Read(config, configProvider)

import ConfigSyntax.ConfigProviderZIOOps

def from(configProvider: Task[ConfigProvider]): ReadZIO[A] =
ReadZIO(config, configProvider.toConfigProviderZIO)
}

implicit class FromConfigProviderOps(c: ConfigProvider.type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package zio.config.magnolia

import zio.ConfigProvider
import zio.config._
import zio.config.derivation.name
import zio.config.magnolia._
import zio.test.Assertion._
import zio.test.{ZIOSpecDefault, _}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package zio.config.typesafe

import zio.Config
import zio.config.magnolia.deriveConfig
import zio.config.read
import zio.test.Assertion.equalTo
import zio.test.{Spec, ZIOSpecDefault, assertZIO}

object TypesafeConfigProviderZIOTest extends ZIOSpecDefault {

final case class DataBaseConfig(url: String)

val configDataBaseConfig: Config[DataBaseConfig] = deriveConfig[DataBaseConfig]

val hocconConfig: String = s"""url = "some_url""""

override def spec: Spec[Any, Config.Error] =
suite("TypesafeConfigProviderZIOTest")(
test("safe read config") {
val result = read(configDataBaseConfig from TypesafeConfigProvider.fromHoconStringZIO(hocconConfig))
val expected = DataBaseConfig("some_url")
assertZIO(result)(equalTo(expected))
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package zio.config.typesafe

import com.typesafe.config._
import zio.config.IndexedFlat.{ConfigPath, KeyComponent}
import zio.{Chunk, ConfigProvider}
import zio.{Chunk, ConfigProvider, Task, ZIO}

import java.io.File
import scala.jdk.CollectionConverters._
Expand Down Expand Up @@ -62,6 +62,24 @@ object TypesafeConfigProvider {
)
}

def fromResourcePathZIO(enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
ZIO.attempt(fromResourcePath(enableCommaSeparatedValueAsList))

def fromHoconFileZIO(file: File, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
ZIO.attempt(fromHoconFile(file, enableCommaSeparatedValueAsList))

def fromHoconFilePathZIO(filePath: String, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
ZIO.attempt(fromHoconFilePath(filePath, enableCommaSeparatedValueAsList))

def fromHoconStringZIO(input: String, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
ZIO.attempt(fromHoconString(input, enableCommaSeparatedValueAsList))

def fromTypesafeConfigZIO(
config: com.typesafe.config.Config,
enableCommaSeparatedValueAsList: Boolean = false
): Task[ConfigProvider] =
ZIO.attempt(fromTypesafeConfig(config, enableCommaSeparatedValueAsList))

private[config] def getIndexedMap(
input: com.typesafe.config.Config
): Map[Chunk[KeyComponent], String] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ package object typesafe {
enableCommaSeparatedValueAsList: Boolean = false
): ConfigProvider =
TypesafeConfigProvider.fromTypesafeConfig(rawConfig, enableCommaSeparatedValueAsList)

def fromResourcePathZIO(enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
TypesafeConfigProvider.fromResourcePathZIO(enableCommaSeparatedValueAsList)

def fromHoconFileZIO(file: File, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
TypesafeConfigProvider.fromHoconFileZIO(file, enableCommaSeparatedValueAsList)

def fromHoconFilePathZIO(filePath: String, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
TypesafeConfigProvider.fromHoconFilePathZIO(filePath, enableCommaSeparatedValueAsList)

def fromHoconStringZIO(input: String, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
TypesafeConfigProvider.fromHoconStringZIO(input, enableCommaSeparatedValueAsList)

def fromTypesafeConfigZIO(
rawConfig: com.typesafe.config.Config,
enableCommaSeparatedValueAsList: Boolean = false
): Task[ConfigProvider] =
TypesafeConfigProvider.fromTypesafeConfigZIO(rawConfig, enableCommaSeparatedValueAsList)
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package zio.config.yaml

import scala.annotation.nowarn
import org.snakeyaml.engine.v2.api.{Load, LoadSettings}
import zio.config._
import zio.config.syntax.IndexKey
import zio.{Chunk, ConfigProvider}
import zio.{Chunk, ConfigProvider, Task, ZIO}

import java.io.{BufferedReader, ByteArrayInputStream, File, FileInputStream, InputStreamReader, Reader}
import java.lang.{Boolean => JBoolean, Double => JDouble, Float => JFloat, Integer => JInteger, Long => JLong}
Expand All @@ -13,12 +12,8 @@ import java.nio.file.Path
import java.{util => ju}
import scala.jdk.CollectionConverters._

@nowarn("cat=unused-imports")
object YamlConfigProvider {

import scala.collection.compat._
import VersionSpecificSupport._

/**
* Retrieve a `ConfigSource` from yaml path.
*
Expand Down Expand Up @@ -111,6 +106,24 @@ object YamlConfigProvider {
fromYamlReader(new BufferedReader(new InputStreamReader(configStream)), enableCommaSeparatedValueAsList)
}

def fromYamlFileZIO(file: File, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
ZIO.attempt(fromYamlFile(file, enableCommaSeparatedValueAsList))

def fromYamlPathZIO(path: Path, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
ZIO.attempt(fromYamlPath(path, enableCommaSeparatedValueAsList))

def fromYamlReaderZIO(
reader: Reader,
enableCommaSeparatedValueAsList: Boolean = false
): Task[ConfigProvider] =
ZIO.attempt(fromYamlReader(reader, enableCommaSeparatedValueAsList))

def fromYamlStringZIO(
yamlString: String,
enableCommaSeparatedValueAsList: Boolean = false
): Task[ConfigProvider] =
ZIO.attempt(fromYamlString(yamlString, enableCommaSeparatedValueAsList))

private[yaml] def getIndexedConfigProvider(
data: AnyRef,
enableCommaSeparatedValueAsList: Boolean = false
Expand Down
18 changes: 18 additions & 0 deletions yaml/shared/src/main/scala/zio/config/yaml/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ package object yaml {
enableCommaSeparatedValueAsList: Boolean = false
): ConfigProvider =
YamlConfigProvider.getIndexedConfigProvider(loadYaml(repr), enableCommaSeparatedValueAsList)

def fromYamlFileZIO(file: File, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
YamlConfigProvider.fromYamlFileZIO(file, enableCommaSeparatedValueAsList)

def fromYamlPathZIO(path: Path, enableCommaSeparatedValueAsList: Boolean = false): Task[ConfigProvider] =
YamlConfigProvider.fromYamlPathZIO(path, enableCommaSeparatedValueAsList)

def fromYamlReaderZIO(
reader: Reader,
enableCommaSeparatedValueAsList: Boolean = false
): Task[ConfigProvider] =
YamlConfigProvider.fromYamlReaderZIO(reader, enableCommaSeparatedValueAsList)

def fromYamlStringZIO(
yamlString: String,
enableCommaSeparatedValueAsList: Boolean = false
): Task[ConfigProvider] =
YamlConfigProvider.fromYamlStringZIO(yamlString, enableCommaSeparatedValueAsList)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ object YamlConfigSpec extends ZIOSpecDefault {
val expected = Child(List(A("str", Nil), B(false, List(C(1), C(2)), Map("hi" -> 1, "bi" -> 2))))

assertZIO(zio.exit)(succeeds(equalTo(expected)))
},
test("save read yaml config") {
final case class DataBaseConfig(url: String)
val configDataBaseConfig: Config[DataBaseConfig] = Config.string("url").to[DataBaseConfig]

val yamlConfig: String = s"""url: "some_url""""
val result = read(configDataBaseConfig from ConfigProvider.fromYamlStringZIO(yamlConfig))
val expected = DataBaseConfig("some_url")
assertZIO(result)(equalTo(expected))
}
)
}
Loading