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

Multi-type items #65

Open
DanySK opened this issue Feb 18, 2021 · 3 comments
Open

Multi-type items #65

DanySK opened this issue Feb 18, 2021 · 3 comments
Labels

Comments

@DanySK
Copy link
Contributor

DanySK commented Feb 18, 2021

Hi,
I'd like to be able to express the following valid configurations:

multitype: somestring
multitype:
  a: map

I can support either one, but not both:

object FooSpec : ConfigSpec("") {
    val multitype by required<String>() // former case
}
object FooSpec : ConfigSpec("") {
    val multitype by required<Map<String, String>>() // latter case
}

Is there a way to capture both cases? I cannot rename the key.

@DanySK
Copy link
Contributor Author

DanySK commented Feb 18, 2021

I tried this strategy:

class MapOrString private constructor(source: Either<String, Map<String, String>) {
    val string: String? = source.leftOrNull
    val map: Map<String, String>? = source.rightOrNull

    constructor(stringDescriptor: String) : this(Either.left(stringDescriptor))
    constructor(map: Map<String, String>) : this(Either.right(map))
}
object FooSpec : ConfigSpec("") {
    val multitype by required<MapOrString>()
}

but it fails with:

Exception in thread "main" com.uchuhimo.konf.source.LoadException: fail to load multitype
	at com.uchuhimo.konf.source.SourceKt.loadItem(Source.kt:638)
	at com.uchuhimo.konf.source.SourceKt$load$1.invoke(Source.kt:653)
	at com.uchuhimo.konf.source.SourceKt$load$1.invoke(Source.kt)
	at com.uchuhimo.konf.BaseConfig.lock(BaseConfig.kt:66)
	at com.uchuhimo.konf.source.SourceKt.load(Source.kt:651)
	at com.uchuhimo.konf.BaseConfig.withSource(BaseConfig.kt:608)
	at com.uchuhimo.konf.source.Loader.string(Loader.kt:204)
        ...
Caused by: com.uchuhimo.konf.source.ObjectMappingException: unable to map source somestring in [type: YAML, content: "
multitype: somestring
"] to value of type MapOrString
	at com.uchuhimo.konf.source.SourceKt.toValue(Source.kt:952)
	at com.uchuhimo.konf.source.SourceKt.loadItem(Source.kt:631)
	... 8 more
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `arrow.core.Either` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: UNKNOWN; line: -1, column: -1]

It looks like Konf never tries secondary constructors...

@DanySK
Copy link
Contributor Author

DanySK commented Feb 18, 2021

I found a way! Secondary constructors need to be annotated with @JsonCreator!
This should really be documented...

@stale
Copy link

stale bot commented Jun 16, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 30 days if no further activity occurs, but feel free to re-open a closed issue if needed.

@stale stale bot added the stale label Jun 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant