ceedubs / ficus Goto Github PK
View Code? Open in Web Editor NEWScala-friendly companion to Typesafe config - moved to https://github.com/iheartradio/ficus
License: MIT License
Scala-friendly companion to Typesafe config - moved to https://github.com/iheartradio/ficus
License: MIT License
I would be helpful if ArbitraryTypeReader offered a mode/setting that adds a runtime check that all keys for a Config object were mapped into the instantiation parameters successfully and that no keys were left un-mapped after instantiation. Current behavior silently ignores Config keys that don't match a parameter when that parameter is optional (Option or default value), allowing simple typo bugs that could be caught at instantiation time to slip into runtime.
Example:
case class Test(foo: String = "foo", bar: Option[String])
val cfg = ConfigFactory.parseString("""
test {
fooTypo: overrideFoo
barTypo: overrideBar
}
""")
val test = cfg.as[Test]("test")
//> test : worksheet.Test = Test(foo,None)
// note default values are not overridden
With typesafe config 1.3.2, as
on root config object fails. Example:
import com.typesafe.config.{ConfigFactory, ConfigValue}
import net.ceedubs.ficus.Ficus._
val config = ConfigFactory.parseString(
"""
foo = {
x = 1
y = [ 0.1 2 ]
z = {
a = 2
}
}
baz = [1 2 3]
""")
// fine
val submap = config.as[Map[String, ConfigValue]]("foo")
// Exception in thread "main" com.typesafe.config.ConfigException$BadPath: path parameter: Invalid path '.': path has a leading, trailing, or two adjacent period '.' (use quoted "" empty string if you want an empty element)
val map1 = config.as[Map[String, ConfigValue]]
// same as above
val map2 = config.as[Map[String, ConfigValue]]("")
Here's the scaste: https://scastie.scala-lang.org/9VG0LqRGQzmbCQ00OHxqfw
Full error:
Exception in thread "main" com.typesafe.config.ConfigException$BadPath: path parameter: Invalid path '.': path has a leading, trailing, or two adjacent period '.' (use quoted "" empty string if you want an empty element)
at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:170)
at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:74)
at com.typesafe.config.impl.PathParser.parsePath(PathParser.java:61)
at com.typesafe.config.impl.Path.newPath(Path.java:230)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:192)
at com.typesafe.config.impl.SimpleConfig.getObject(SimpleConfig.java:268)
at com.typesafe.config.impl.SimpleConfig.getConfig(SimpleConfig.java:274)
at com.typesafe.config.impl.SimpleConfig.getConfig(SimpleConfig.java:41)
at net.ceedubs.ficus.readers.CollectionReaders$$anon$2.read(CollectionReaders.scala:28)
at net.ceedubs.ficus.readers.CollectionReaders$$anon$2.read(CollectionReaders.scala:26)
at net.ceedubs.ficus.FicusConfig.as(FicusConfig.scala:10)
at net.ceedubs.ficus.FicusConfig.as$(FicusConfig.scala:10)
at net.ceedubs.ficus.SimpleFicusConfig.as(FicusConfig.scala:21)
at net.ceedubs.ficus.FicusConfig.as(FicusConfig.scala:12)
at net.ceedubs.ficus.FicusConfig.as$(FicusConfig.scala:12)
at net.ceedubs.ficus.SimpleFicusConfig.as(FicusConfig.scala:21)
at fed.FicusRoot$.delayedEndpoint$fed$FicusRoot$1(FicusRoot.scala:25)
at fed.FicusRoot$delayedInit$body.apply(FicusRoot.scala:7)
at scala.Function0.apply$mcV$sp(Function0.scala:34)
at scala.Function0.apply$mcV$sp$(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App.$anonfun$main$1$adapted(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:389)
at scala.App.main(App.scala:76)
at scala.App.main$(App.scala:74)
at fed.FicusRoot$.main(FicusRoot.scala:7)
at fed.FicusRoot.main(FicusRoot.scala)
I'm currently getting familiar with the library. Possible use case would be mapping the whole config to a simple case class. I think I saw in the README that mapping to arbitrary classes is supported.
Any estimate on when Scala 2.11 artifacts will be published for Ficus? It's the only dependency holding me back at the moment.
HOCON specification recommends hyphen-separated
settings over camelCase
Using case classes like the following works
case class MySetting(`hyphen-separated-setting`: String)
but it is a bit clumsy in the source code.
Wouldn't it be nice to have an option to automagically convert camelCase
into hyphen-separated
?
If you check Maven Central (http://mvnrepository.com/artifact/net.ceedubs/ficus_2.10/1.0.0), you'll see that ficus depends on scala-compiler
somehow. And that increases size of required libraries (13Mb for scala-compiler
instead of 4Mb for standalone scala-reflect
).
Right now all I see in sbt
script is provided
dependency for scala-reflect
, without any mention of scala-compiler
...
Upgrade the dependency. https://github.com/typesafehub/config/blob/master/NEWS.md
Please, publish for Scala 2.12
FicusConfig
inherit implicit def arbitraryTypeValueReader[T]: ValueReader[T]
from ArbitraryTypeReader
. As visible in current scope, those macro reader then takes precedence over any custom reader for case classes defined in companion objects.
To be able to use custom extraction, user needs to explicitly import correct custom extractor to local scope.
Test spec: https://gist.github.com/seigert/ebd10c123f91d3b894c4
Since BigDecimal
and BigInt
are in predef, ficus should support these readers by default.
Here is a pull request #17. It also throws the correct ConfigError.WrongType exception if it fails to do the reading
We found it quite handy to read a bunch of variables from some implicit config like this:
val a = "path.to.variable".as[String]
val b = "another.path".as[FiniteDuration]
...
Please consider adding simple helper for this, like:
implicit class ConfigPathHelper(val path: String) {
def as[T: ValueReader](implicit config: Config): T = {
config.as[T](path)
}
}
Using maven and Scala 2.10.3, getting errors for e.g. scala-reflect-2.10.2.jar dependency. It can be overridden sure, but with 2.10 having better compatibility I guess you could depend on >= 2.10.2?
Ficus seems awesome at reading config files, but what about writing or updating them? There is nearly no reference to how it writes back.
I have an example like this:
"load embedded config with ficus" in {
import net.ceedubs.ficus.readers.ArbitraryTypeReader._
import net.ceedubs.ficus.Ficus._
val config = ConfigFactory.parseString(
"""a { value = 2 }
|b { value = 3 }""".stripMargin)
case class Conf(value:Int)
config.as[Conf]("a").value must_==(2)
config.as[Conf]("b").value must_==(3)
def getConf(config:Config) : Conf = {
config.as[Conf]
}
val a:Conf = getConf(config.getConfig("a"))
val b:Conf = getConf(config.getConfig("b"))
}
where 'getConf' does not compile. What I want is to make 'getConf' method working as a config parser, which is given config part only, without knowing what the surrounding key was.
currently I nned to do config.asConf or else I do not get a 'Conf' instance.
is it something missing in Ficus, or am I doing something wrong?
(brain dumping)
After having used shapeless' LabelledGeneric
quite a lot recently, I'm pretty sure it should be possible to create a nested bunch of case classes and have it automatically populated with the fqns as defined by the field names from a config file (via your typed providers, which can be pulled in implicitly).
This is something I've wanted for a while and unfortunately I've been stuck in a project for the last 18 months which has written its own property layer (my opinion withheld) so I never had a burning desire to implement this idea.
If I ever get round to it, I'll certainly send you a PR.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.