All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.apollographql.apollo3.api.CustomScalarAdapters.kt Maven / Gradle / Ivy

There is a newer version: 4.0.0-beta.7
Show newest version
package com.apollographql.apollo3.api

import com.apollographql.apollo3.annotations.ApolloExperimental
import kotlin.jvm.JvmField

/**
 * A wrapper around a Map used to retrieve custom scalar adapters at runtime
 */
class CustomScalarAdapters private constructor(
    customScalarAdapters: Map>,
    private val unsafe: Boolean,
) : ExecutionContext.Element {

  private val adaptersMap: Map> = customScalarAdapters

  fun  adapterFor(name: String): Adapter? {
    @Suppress("UNCHECKED_CAST")
    return adaptersMap[name] as Adapter?
  }

  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 scalar Adapter?")
    } as Adapter
  }

  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 unsafe = false

    fun  add(
        name: String,
        adapter: Adapter,
    ) = apply {
      adaptersMap[name] = adapter
    }

    fun  add(
        customScalarType: CustomScalarType,
        customScalarAdapter: Adapter,
    ) = apply {
      adaptersMap[customScalarType.name] = customScalarAdapter
    }


    fun addAll(customScalarAdapters: CustomScalarAdapters) = apply {
      this.adaptersMap.putAll(customScalarAdapters.adaptersMap)
    }

    @ApolloExperimental
    fun unsafe(unsafe: Boolean) = apply {
      this.unsafe = unsafe
    }

    fun clear() {
      adaptersMap.clear()
    }

    fun build() = CustomScalarAdapters(adaptersMap, unsafe)
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy