Giter Site home page Giter Site logo

config4k's Introduction

Config4k

Build Status codecov ktlint Maven Central Sonatype Nexus (Snapshots) javadoc GitHub

Config for Kotlin.

Config4k is a lightweight Typesafe Config wrapper for Kotlin and inspired by ficus, providing simple extension functions Config.extract<T> and Any.toConfig to convert between Config and Kotlin Objects.

Documentation

For more information see the documentation

Snapshots

All snapshot artifacts are available in the Sonatype snapshots repository.

Contribute

Would you like to contribute to Config4k?
Take a look at CONTRIBUTING.md

config4k's People

Contributors

alexbolgov avatar crazymoonkin avatar dependabot[bot] avatar eduardompinto avatar forestone23 avatar ihostage avatar jbunting avatar josepanguera avatar marcelstoer avatar martintreurnicht avatar michalciolek avatar mkobit avatar mmorihiro avatar red-avtovo avatar renovate[bot] avatar roxspring avatar vjames19 avatar yoavya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

config4k's Issues

arbitraryType to Config

Tests

  • Primitive types
data class Person(name: String, age: Int)

Person("foo", 20).toConfig("person").extract<Person>("person") shouldBe Person("foo", 20)
  • ArbitraryTypeCollection
data class Family(val persons: List<Person>)

val family = Family(listOf(Person("foo", 20), Person("bar", 25)))
family.toConfig("family").extract<Family>("family") shouldBe family
  • Enum
  • Nullable

Reference

ConfigException$BadPath when loading config with empty path.

I load config like this
ConfigFactory.load().extract("")
Then it occurred ConfigException$BadPath
Maybe I misunderstanding "use quoted "" empty string if you want an empty element"?

Exception in thread "main" java.lang.ExceptionInInitializerError
	at io.monchi.pucheen.PucheenKt.main(Pucheen.kt:74)
Caused by: 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.hasPathPeek(SimpleConfig.java:83)
	at com.typesafe.config.impl.SimpleConfig.hasPath(SimpleConfig.java:95)
	at io.github.config4k.readers.Reader$getValue$1.invoke(Reader.kt:16)
	at io.github.config4k.readers.Reader$getValue$1.invoke(Reader.kt:13)
	at io.monchi.pucheen.Pucheen.loadConfig(Pucheen.kt:79)
	at io.monchi.pucheen.Pucheen.<init>(Pucheen.kt:22)
	at io.monchi.pucheen.Pucheen.<clinit>(Pucheen.kt:20)
	... 1 more

Publish to Maven Central

Hi, @mmorihiro! ๐Ÿ‘‹
Can you publish the artifacts to Maven Central?
We use Config4k as a transitive dependency of our library and our customers need manually add JCenter to the list of repositories.

support for nullable

reference: OptionReader.scala

val config = ConfigFactory.parseString("key = 1")
val nullableValue = config.extract<Int?>
nullableValue!! shouldBe 1
val config = ConfigFactory.parseString("")
val nullableValue = config.extract<Int?>
nullableValue shouldBe null

Readme.md

  • Add new supported type
  • Make https://github.com/config4k/config4k/blob/master/src/test/io/github/config4k/TestExtension.kt shorter
  • Replace 0.1.0 with xxx

Feature request: treat absent values for dataclasses as default

Suppose we have a config like this:

some_key {
      importantProperty = some_value
}

and trying to read data class by some_key:

data class SomeKeyConfig(
    val importantProperty: String,
    val minorProperty: Int = 500
)

val config = Config.extract<SomeKeyConfig>("some_key")

Current behavior is IllegalArgumentException. So, one should mark minorProperty as nullable and provide custom getter. It would be nice to avoid that and simply get a data class with default values where needed.

1.4.2 release was rolled back

First of all, thanks for making this library. Ran into an issue today.

I think that the rollback of releases is not a good practice. I'd suggest in the future to release a new version 1.4.3 instead.

This rollback removed the artifact from bintray and maven central. This will cause builds to break.

d901a4c

Upgrade to latest KotlinTest

The improvement with this upgrade is to replace init block with lambda expression in all test classes.

// Now
class MyTests : WordSpec() {
  init {
    // tests here
  }
}
// Goal
class MyTests : WordSpec({
  // tests here
})

Better version management

Went to releases page and 0.4.0 release isn't listed there. It would be nice to have some consistency around releases, have them tagged on releases page and perhaps have a list of pull requests merged etc. Right now it seems there is quite a bit of pull request contributions coming in. I would even suggest doing releases via Travis (for minor versions in any case). Once a pull request gets merged it could just do a minor release (0.4.++x). You can then always just do a major release manually when you feel like it, or feel there will be breaking changes. If there is a pull request that you do not want to trigger a release, you can always re-target it to another branch, like develop and merge that manually at a later stage

Publish 0.4.1

Looks like 0.4.1 was tagged recently but isn't listed properly under the releases and doesn't appear on bintray. Would be good to see the release completed and published, particurly to using #63 from a published release.

Don't mean to hound you if the release is still in-progress, but thought I'd raise an issue in case the release process had failed without you noticing.

Project status?

Is this project still being maintained? We are using Kotlin and are wondering whether to just use the original typesafe library vs. this.

Feature request: Config as Read-Only Property Delegate

I have an object and want to configure its properties from a Config instance. Currently, I'm doing something like this:

class Thing(config: Config) {
  val property = config.getBoolean("Thing.property")
}

But it feels like we should be able to do this more cleanly if a Config instance could be used as a read-only property delegate:

class Thing(config: Config) {
  val property: Boolean by config
}

Pull request linked below supporting similar syntax.

(I'm also open to suggestions of other ways to configure all properties of an existing instance from a Config object - but delegated properties feels like a good route to explore)

Exception extract ChronoField

exceptions only with extract. Need to do a custom type?

data class RunnableConfig(
    val timeStart: String,
    val dateStart: String,
    val unitOverflow: ChronoField
)

val runnable = RunnableConfig("20:20",  "2019-12-01", ChronoField.DAY_OF_MONTH)
val config = runnable.toConfig("runnable")
println(config)

val parseRunnable = config.extract<RunnableConfig>("runnable") //exception
println(parseRunnable)
Exception in thread "main" io.github.config4k.Config4kException$WrongEnum: expected : [NanoOfSecond, NanoOfDay, MicroOfSecond, MicroOfDay, MilliOfSecond, MilliOfDay, SecondOfMinute, SecondOfDay, MinuteOfHour, MinuteOfDay, HourOfAmPm, ClockHourOfAmPm, HourOfDay, ClockHourOfDay, AmPmOfDay, DayOfWeek, AlignedDayOfWeekInMonth, AlignedDayOfWeekInYear, DayOfMonth, DayOfYear, EpochDay, AlignedWeekOfMonth, AlignedWeekOfYear, MonthOfYear, ProlepticMonth, YearOfEra, Year, Era, InstantSeconds, OffsetSeconds], actually : DAY_OF_MONTH
	at io.github.config4k.readers.EnumReader$1.invoke(EnumReader.kt:14)
	at io.github.config4k.readers.EnumReader$1.invoke(EnumReader.kt:8)
	at io.github.config4k.readers.Reader$getValue$1.invoke(Reader.kt:18)
	at io.github.config4k.readers.Reader$getValue$1.invoke(Reader.kt:15)
	at io.github.config4k.readers.ArbitraryTypeReaderKt.extractWithParameters(ArbitraryTypeReader.kt:29)
	at io.github.config4k.readers.ArbitraryTypeReader$1.invoke(ArbitraryTypeReader.kt:14)
	at io.github.config4k.readers.ArbitraryTypeReader$1.invoke(ArbitraryTypeReader.kt:13)
	at io.github.config4k.readers.Reader$getValue$1.invoke(Reader.kt:18)
	at io.github.config4k.readers.Reader$getValue$1.invoke(Reader.kt:15)
	at opz.power.experimental.CunstomTypeConfigKt.main(cunstomTypeConfig.kt:164)
	at opz.power.experimental.CunstomTypeConfigKt.main(cunstomTypeConfig.kt)

support for list

val config = ConfigFactory.parseString("key = [0, 1, 2]")
val list = config.extract<List<Int>>("key")
list shouldBe listOf(0, 1, 2)

toConfig with keys that need to be quoted crashes

trying to switch from gson to config4k / hocon
i encountered a issue when trying to serialize keys containing @ and other invalid characters

private val default = hashMapOf(
       "irc.esper" to hashMapOf(
           "[email protected]" to 3,
           "[email protected]" to 0
        ),
       "discord.ruby" to hashMapOf(
           "0294827264937295336" to 0
        )
)
val config: Config = default.toConfig("permissions")
configFile.writeText(config.root().render(options))

this code throws the following message

Caused by: com.typesafe.config.ConfigException$BadPath: path parameter: Invalid path '[email protected]': Token not allowed in path expression: '@' (Reserved character '@' is not allowed outside quotes) (you can double-quote this token if you really want it here)

the exception message mentiones double quoting it
so i tried and this works and parses fine.. although a lack of support for HashMap, does not make it easier

permissions {
    "irc.esper" {
        "[email protected]": 3
        "[email protected]": 0
    }
}

Kotlin bug causes `extract` to fail when using Evaluate Expression in debugger

To repro, debug any project and stop at a breakpoint. Open the Evaluate Expression dialog and run the following:

ConfigFactory.load("foo").extract<String>("bar")

You'll get a ClassNotFoundException that is ultimately caused by this bug in IntelliJ: https://youtrack.jetbrains.com/issue/KT-29382

This can be avoided by making a small tweak in https://github.com/config4k/config4k/blob/master/src/main/io.github.config4k/Extension.kt, changing:

inline fun <reified T> Config.extract(path: String): T {
    val genericType = object : TypeReference<T>() {}.genericType()

to

class DummySubclass<T> : TypeReference<T>()

inline fun <reified T> Config.extract2(path: String): T {
    val genericType = DummySubclass<T>().genericType()

Would you accept a PR that contained that change? Thanks.

Upgrade to kotlin 1.2.x

Config4k uses kotlin-reflect 1.1.3, and we having an issue with switching to 1.2.0 with compile dependency on kotlin-reflect 1.2.0.

support for map

reference: CollectionReaders.scala

val inner =   """
        |  {
        |    key1 = 1
        |    key2 = 2
        |  }
        """.trimMargin()
val config= ConfigFactory.parseString("nest = $inner")
val map = config.extract<Map<String, int>>("nest")
map shouldBe mapOf("key1" to 1, "key2" to 2)

Support `private` data classes for extraction

  • Java 11
package mkobit.example

import com.typesafe.config.ConfigFactory
import io.github.config4k.extract

private data class MyConfig(val something: String, val pizza: Pizza) {
    data class Pizza(val flavor: String)
}

fun main() {
    val config = ConfigFactory.parseString("""
        something = "This value comes from complex-app's complex1.conf"
        pizza {
          flavor = "pepperoni"
        }
    """.trimIndent())
    val extracted = config.extract<MyConfig>()

    println(extracted)
}

Fails with

Exception in thread "main" kotlin.reflect.full.IllegalCallableAccessException: java.lang.IllegalAccessException: class kotlin.reflect.jvm.internal.calls.CallerImpl$Constructor cannot access a member of class mkobit.example.MyConfig with modifiers "public"
	at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:224)
	at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod$kotlin_reflect_api(KCallableImpl.kt:152)
	at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:110)
	at io.github.config4k.readers.ArbitraryTypeReaderKt.extractWithParameters(ArbitraryTypeReader.kt:32)
	at io.github.config4k.readers.ArbitraryTypeReaderKt.extractWithParameters$default(ArbitraryTypeReader.kt:19)
	at io.github.config4k.readers.SelectReader.extractWithoutPath(SelectReader.kt:66)
	at mkobit.example.Mkexample1Kt.main(mkexample1.kt:24)
	at mkobit.example.Mkexample1Kt.main(mkexample1.kt)
Caused by: java.lang.IllegalAccessException: class kotlin.reflect.jvm.internal.calls.CallerImpl$Constructor cannot access a member of class mkobit.example.MyConfig with modifiers "public"
	at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
	at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
	at kotlin.reflect.jvm.internal.calls.CallerImpl$Constructor.call(CallerImpl.kt:41)
	at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:106)
	... 7 more

Could be useful to be able to hide some of the data views of config.

Support "custom types"

So as I've been using config4k, I've run into a few types that aren't handled natively, and honestly there's not a good way to bake it into the library. It would be nice if it were possible to register custom types in order to extend the functionality available. I've been playing with some approaches and would be happy to implement but I wanted to have a quick discussion around design. Right now I've got something that looks like this working:

diff --git a/src/main/io.github.config4k/CustomType.kt b/src/main/io.github.config4k/CustomType.kt
new file mode 100644
index 0000000..bc43459
--- /dev/null
+++ b/src/main/io.github.config4k/CustomType.kt
@@ -0,0 +1,18 @@
+package io.github.config4k
+
+import com.typesafe.config.Config
+
+interface CustomType {
+    fun testParse(clazz: ClassContainer): Boolean
+    fun testToConfig(obj: Any): Boolean
+    fun parse(clazz: ClassContainer, config: Config, name: String): Any
+    fun toConfig(obj: Any, name: String): Config
+}
+
+private val mutableRegistry: MutableList<CustomType> = mutableListOf()
+
+val customTypeRegistry: List<CustomType> = mutableRegistry.toList()
+
+fun registerCustomType(customType: CustomType) {
+    mutableRegistry.add(customType)
+}
\ No newline at end of file
diff --git a/src/main/io.github.config4k/Extension.kt b/src/main/io.github.config4k/Extension.kt
index 8cca803..ef81ebc 100644
--- a/src/main/io.github.config4k/Extension.kt
+++ b/src/main/io.github.config4k/Extension.kt
@@ -3,6 +3,8 @@ package io.github.config4k
 import com.typesafe.config.Config
 import com.typesafe.config.ConfigException
 import com.typesafe.config.ConfigFactory
+import com.typesafe.config.ConfigValueFactory
+import com.typesafe.config.impl.ConfigImpl
 import io.github.config4k.readers.SelectReader
 import java.io.File
 import java.nio.file.Path
@@ -41,6 +43,11 @@ inline fun <reified T> Config.extract(path: String): T {
  */
 fun Any.toConfig(name: String): Config {
     val clazz = this.javaClass.kotlin
+    for (customType in customTypeRegistry) {
+        if (customType.testToConfig(this)) {
+            return customType.toConfig(this, name)
+        }
+    }
     val map = when {
         clazz.javaPrimitiveType != null -> mapOf(name to this)
         this is String -> mapOf(name to this)
@@ -67,5 +74,6 @@ fun Any.toConfig(name: String): Config {
         clazz.objectInstance != null -> mapOf(name to emptyMap<String, Any>())
         else -> throw Config4kException.UnSupportedType(clazz)
     }
+
     return ConfigFactory.parseMap(map)
 }
diff --git a/src/main/io.github.config4k/readers/SelectReader.kt b/src/main/io.github.config4k/readers/SelectReader.kt
index c2ea8e4..454b78b 100644
--- a/src/main/io.github.config4k/readers/SelectReader.kt
+++ b/src/main/io.github.config4k/readers/SelectReader.kt
@@ -5,6 +5,7 @@ import com.typesafe.config.ConfigMemorySize
 import com.typesafe.config.ConfigValue
 import io.github.config4k.ClassContainer
 import io.github.config4k.Config4kException
+import io.github.config4k.customTypeRegistry
 import java.io.File
 import java.nio.file.Path
 import java.time.Duration
@@ -24,33 +25,39 @@ object SelectReader {
      * @param clazz a instance got from the given type by reflection
      * @throws Config4kException.UnSupportedType if the passed type is not supported
      */
-    fun getReader(clazz: ClassContainer) =
-            when (clazz.mapperClass) {
-                Int::class -> IntReader()
-                String::class -> StringReader()
-                Boolean::class -> BooleanReader()
-                Byte::class -> ByteReader()
-                Double::class -> DoubleReader()
-                Long::class -> LongReader()
-                Duration::class -> DurationReader()
-                Period::class -> PeriodReader()
-                TemporalAmount::class -> TemporalAmountReader()
-                ConfigMemorySize::class -> MemorySizeReader()
-                Config::class -> ConfigReader()
-                ConfigValue::class -> ConfigValueReader()
-                List::class -> ListReader(clazz.typeArguments)
-                Set::class -> SetReader(clazz.typeArguments)
-                Map::class -> MapReader(clazz.typeArguments)
-                File::class -> FileReader()
-                Path::class -> PathReader()
-                else ->
-                    when {
-                        clazz.mapperClass.java.isArray ->
-                            ArrayReader(clazz.mapperClass.java.componentType.kotlin)
-                        clazz.mapperClass.java.isEnum -> EnumReader(clazz.mapperClass)
-                        clazz.mapperClass.primaryConstructor != null -> ArbitraryTypeReader(clazz)
-                        clazz.mapperClass.objectInstance != null -> ObjectReader(clazz)
-                        else -> throw Config4kException.UnSupportedType(clazz.mapperClass)
-                    }
-            }.getValue
+    fun getReader(clazz: ClassContainer): (Config, String)->Any? {
+        for (customType in customTypeRegistry) {
+            if (customType.testParse(clazz)) {
+                return Reader({ config, name -> customType.parse(clazz, config, name) }).getValue
+            }
+        }
+        return when (clazz.mapperClass) {
+            Int::class -> IntReader()
+            String::class -> StringReader()
+            Boolean::class -> BooleanReader()
+            Byte::class -> ByteReader()
+            Double::class -> DoubleReader()
+            Long::class -> LongReader()
+            Duration::class -> DurationReader()
+            Period::class -> PeriodReader()
+            TemporalAmount::class -> TemporalAmountReader()
+            ConfigMemorySize::class -> MemorySizeReader()
+            Config::class -> ConfigReader()
+            ConfigValue::class -> ConfigValueReader()
+            List::class -> ListReader(clazz.typeArguments)
+            Set::class -> SetReader(clazz.typeArguments)
+            Map::class -> MapReader(clazz.typeArguments)
+            File::class -> FileReader()
+            Path::class -> PathReader()
+            else ->
+                when {
+                    clazz.mapperClass.java.isArray ->
+                        ArrayReader(clazz.mapperClass.java.componentType.kotlin)
+                    clazz.mapperClass.java.isEnum -> EnumReader(clazz.mapperClass)
+                    clazz.mapperClass.primaryConstructor != null -> ArbitraryTypeReader(clazz)
+                    clazz.mapperClass.objectInstance != null -> ObjectReader(clazz)
+                    else -> throw Config4kException.UnSupportedType(clazz.mapperClass)
+                }
+        }.getValue
+    }

Thoughts?

custom exception

Problem

TODO() is used.

 fun getReader(type: KClass<*>): Reader<*> =
            when (type) {
                else -> TODO() // Custom exception will replace TODO()
            }

Resolution

A custom exception Config4kException will be defined.

`java.time.Duration` is not supported when toConfig

Describe the bug

import io.github.config4k.toConfig
 import java.time.Duration
 
 Duration.ofMinutes(1).toConfig("")

throw

io.github.config4k.Config4kException$UnSupportedType: type: java.time.Duration is not supported
	at io.github.config4k.ExtensionKt.toConfig(Extension.kt:90)

Expected behavior
toConfig works.

It's not on maven

I'm trying to use the library from SBT:

resolvers += Resolver.jcenterRepo
libraryDependencies += "io.github.config4k" % "config4k" % "0.4.1"

I've got this error:

[error]   not found: https://repo1.maven.org/maven2/io/github/config4k/config4k/0.4.1/config4k-0.4.1.pom

Should I use a different resolver?

sorry, wrong repo

I have environment variables that I'd like to access via config specs:

export KAFKA_CLIENT_CERT=some_cert
export KAFKA_CLIENT_CERT_KEY=some_cert_key

Here's my config spec:

object KafkaConfigSpec : ConfigSpec("kafka") {
    val clientCert by optional(name="client.cert", default = "")
    val clientCertKey by optional(name="client.cert.key", default = "")
}

When I try to load the config:

Config { addSpec(KafkaConfigSpec) }.withSourceFrom.env()

I get the following stack trace:

Exception in thread "main" com.uchuhimo.konf.NameConflictException: item kafka.client.cert.key cannot be added
	at com.uchuhimo.konf.BaseConfig.addSpec(BaseConfig.kt:415)
	at com.uchuhimo.konf.Config$Companion.invoke(Config.kt:344)

Use trimIndent instead of trimMargin in test

fun String.toConfig(): Config = ConfigFactory.parseString(this.trimIndent())

ConfigFactory.parseStringใฎๅ†—้•ทใช้ƒจๅˆ†ใ‚’ใชใใ™ใ“ใจใงใ€ใƒ†ใ‚นใƒˆใŒใ‹ใชใ‚Š่ชญใฟใ‚„ใ™ใใชใ‚‹ใ€‚

Support Sealed-classes / custom Deserializers in general

A great addition (one which i actually need ) would be to support sealed classes, based on their shape.
Currently, i'm using json with GSON, using a custom deserializer for my use case, where i decide the concrete type (sub-type of my sealed class) based on if the value is of type List, Int or String.

having something like this, be it automagically or be it by having something like custom deserializers, would be really needed.

I know i could just extract the data manually and then manually construct my objects, but thats reallly inconvenient.

I think if you added the option do implement custom deserializers that would help a lot!

support for set and array

val config = ConfigFactory.parseString("key = [0, 1, 1, 2]")

val set = config.extract<Set<Int>>("key")
set should haveSize(3)
set shouldBe setOf(0, 1, 2)

val array = config.extract<Array<Int>>("key")
array shouldBe arrayOf(0, 1, 1, 2)

Is not compatible with Kotlin 1.2.21

It seems that KClasses does not exist anymore in kotlin/reflect/KClasses

Example:

    fun database(): Database {
        return config.extract("db")
    }

Result:

java.lang.NoClassDefFoundError: kotlin/reflect/KClasses
	at io.github.config4k.readers.SelectReader.getReader(SelectReader.kt:40)

Empty sources and javadoc jars

Hello,

I've just found out, that the javadoc and sources jars in the last release (0.4.2) are empty. Both have only 261B and contain only MANIFEST and nothing else.

Could this be fixed please? Our documentation contains references to config4k, which are linked to config4k docs on javadoc.io. But since the javadoc jar is empty, javadoc.io has trouble parsing it, as you can see at the linked url.

Feature request: In the future think about backward compatibility

Hi!
I understand, that 0.X.Y version is not final and stable. But drop backward compatibility in the bugfix version is very unexpected. ๐Ÿ˜ž

We use two libraries, both dependent on config4k, but use version 0.4.0 and 0.4.1. And these versions are incompatible. ๐Ÿ˜ข

TypeReference.kt (0.4.0)

open class TypeReference<T> {
    fun genericType(): List<ClassContainer> {
       ...
    }
}

TypeReference.kt (0.4.1)

open class TypeReference<T> {
    fun genericType(): Map<String, ClassContainer> {
       ...
    }
}

Support for primitive types

Add an extension function extract

Example

value = 0
config.extract<Int>("value") shouldBe 0

Support types

  • Boolean
  • Int
  • Long
  • Double
  • String
  • Config
  • ConfigValue

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.