I have a KMP Ktor client API lib written in Common...
# ktor
m
I have a KMP Ktor client API lib written in Common. The consumer can set a config for a httpclient. Currently I have this as
Copy code
object API {
    var defaultClient = HttpClient {}
    fun <T : HttpClientEngineConfig> setDefaultClientConfig(block: HttpClientConfig<T>.() -> Unit) {
          defaultClient = defaultClient.config(block as HttpClientConfig<*>.() -> Unit)
    }
}
Is there a way to achieve this without doing an unchecked cast?
This is so that I can specify concrete client config depending on the target. For example in JVM The consumer can do this now.
Copy code
API.setDefaultClientConfig<OkHttpConfig> {
   install(UserAgent) {
     agent = "MyAgent"
   }

  engine {
    preconfigured = okHttpClient()
    addNetworkInterceptor(DownloadProgressInterceptor(...))
  }
}
a
A consumer wouldn’t necessarily know which engine
HttpClient { }
defaults to here in case there are multiple engines in the classpath. To do this without an unchecked cast, the engine also needs to be provided by a consumer. But overall that’s a dangerous looking pattern in
API
m
Yes, I wanted to avoid that, I have made them typed for each target. But it is still a unchecked cast
Copy code
fun API.setDefaultClientConfig(block: HttpClientConfig<OkHttpConfig>.() -> Unit){
    @Suppress("UNCHECKED_CAST")
    defaultClient = defaultClient.config(block as HttpClientConfig<*>.() -> Unit)
}
a
I think is better if your API should accept a
HttpClient
instead of the config block