commonMain.com.apollographql.apollo3.api.CustomScalarAdapters.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apollo-api-jvm Show documentation
Show all versions of apollo-api-jvm Show documentation
Apollo GraphQL API classes
package com.apollographql.apollo3.api
import com.apollographql.apollo3.annotations.ApolloDeprecatedSince
import com.apollographql.apollo3.annotations.ApolloDeprecatedSince.Version.v3_0_0
import com.apollographql.apollo3.annotations.ApolloDeprecatedSince.Version.v3_2_1
import com.apollographql.apollo3.annotations.ApolloExperimental
import com.apollographql.apollo3.api.internal.Version2CustomTypeAdapterToAdapter
import kotlin.jvm.JvmField
/**
* A wrapper around a Map used to retrieve custom scalar adapters at runtime
*/
class CustomScalarAdapters private constructor(
customScalarAdapters: Map>,
// We piggyback CustomScalarAdapters to pass around a context which is used in the Adapters at parse time.
// This is currently used for @skip/@include and @defer.
// Ideally it should be passed as its own parameter, but we're avoiding a breaking change.
// See https://github.com/apollographql/apollo-kotlin/pull/3813
val adapterContext: AdapterContext,
private val unsafe: Boolean
) : ExecutionContext.Element {
private val adaptersMap: Map> = customScalarAdapters
fun responseAdapterFor(customScalar: CustomScalarType): Adapter {
@Suppress("UNCHECKED_CAST")
return when {
adaptersMap[customScalar.name] != null -> {
adaptersMap[customScalar.name]
}
/**
* Below are shortcuts to save the users a call to `registerCustomScalarAdapter`
*/
customScalar.className == "com.apollographql.apollo3.api.Upload" -> {
UploadAdapter
}
customScalar.className in listOf("kotlin.String", "java.lang.String") -> {
StringAdapter
}
customScalar.className in listOf("kotlin.Boolean", "java.lang.Boolean") -> {
BooleanAdapter
}
customScalar.className in listOf("kotlin.Int", "java.lang.Int") -> {
IntAdapter
}
customScalar.className in listOf("kotlin.Double", "java.lang.Double") -> {
DoubleAdapter
}
customScalar.className in listOf("kotlin.Long", "java.lang.Long") -> {
LongAdapter
}
customScalar.className in listOf("kotlin.Float", "java.lang.Float") -> {
FloatAdapter
}
customScalar.className in listOf("kotlin.Any", "java.lang.Object") -> {
AnyAdapter
}
unsafe -> PassThroughAdapter()
else -> error("Can't map GraphQL type: `${customScalar.name}` to: `${customScalar.className}`. Did you forget to add a CustomScalarAdapter?")
} as Adapter
}
@Deprecated("Use adapterContext.variables() instead", ReplaceWith("adapterContext.variables()"))
@ApolloDeprecatedSince(v3_2_1)
fun variables() = adapterContext.variables()
override val key: ExecutionContext.Key<*>
get() = Key
companion object Key : ExecutionContext.Key {
/**
* An empty [CustomScalarAdapters]. If the models were generated with some custom scalars, parsing will fail
*/
@JvmField
val Empty = Builder().build()
/**
* Unsafe [CustomScalarAdapters]. They can only be used with `MapJsonReader` and `MapJsonWriter`. It will passthrough the values using
* `MapJsonReader.nextValue` and `MapJsonWriter.value()`
*/
@JvmField
@ApolloExperimental
val PassThrough = Builder().unsafe(true).build()
}
fun newBuilder() = Builder().addAll(this)
class Builder {
private val adaptersMap: MutableMap> = mutableMapOf()
private var adapterContext: AdapterContext = AdapterContext.Builder().build()
private var unsafe = false
fun add(
customScalarType: CustomScalarType,
customScalarAdapter: Adapter,
) = apply {
adaptersMap[customScalarType.name] = customScalarAdapter
}
@Suppress("DEPRECATION")
@Deprecated("Used for backward compatibility with 2.x")
@ApolloDeprecatedSince(v3_0_0)
fun add(
customScalarType: CustomScalarType,
customTypeAdapter: CustomTypeAdapter,
) = apply {
adaptersMap[customScalarType.name] = Version2CustomTypeAdapterToAdapter(customTypeAdapter)
}
fun addAll(customScalarAdapters: CustomScalarAdapters) = apply {
this.adaptersMap.putAll(customScalarAdapters.adaptersMap)
}
@ApolloExperimental
fun unsafe(unsafe: Boolean) = apply {
this.unsafe = unsafe
}
fun clear() {
adaptersMap.clear()
}
@Suppress("DEPRECATION")
fun build() = CustomScalarAdapters(adaptersMap, adapterContext, unsafe)
fun adapterContext(adapterContext: AdapterContext): Builder = apply {
this.adapterContext = adapterContext
}
@Deprecated("Use AdapterContext.Builder.variables() instead")
@ApolloDeprecatedSince(v3_2_1)
fun variables(variables: Executable.Variables): Builder = apply {
adapterContext = adapterContext.newBuilder().variables(variables).build()
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy