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

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

package com.apollographql.apollo3.api

import com.apollographql.apollo3.api.json.JsonReader
import com.apollographql.apollo3.api.json.JsonWriter
import com.apollographql.apollo3.api.json.MapJsonReader.Companion.buffer
import com.apollographql.apollo3.api.json.MapJsonWriter
import com.apollographql.apollo3.api.json.buildJsonString
import com.apollographql.apollo3.api.json.writeAny
import kotlin.jvm.JvmName
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmSuppressWildcards

class ListCompositeAdapter(private val wrappedAdapter: CompositeAdapter) : CompositeAdapter> {
  override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): List {
    reader.beginArray()
    val list = mutableListOf()
    while (reader.hasNext()) {
      list.add(wrappedAdapter.fromJson(reader, adapterContext))
    }
    reader.endArray()
    return list
  }

  override fun toJson(writer: JsonWriter, value: List, adapterContext: CompositeAdapterContext) {
    writer.beginArray()
    value.forEach {
      wrappedAdapter.toJson(writer, it, adapterContext)
    }
    writer.endArray()
  }
}

class NullableCompositeAdapter(private val wrappedAdapter: CompositeAdapter) : CompositeAdapter<@JvmSuppressWildcards T?> {
  init {
    check(wrappedAdapter !is NullableCompositeAdapter<*>) {
      "The adapter is already nullable"
    }
  }

  override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): T? {
    return if (reader.peek() == JsonReader.Token.NULL) {
      reader.skipValue()
      null
    } else {
      wrappedAdapter.fromJson(reader, adapterContext)
    }
  }

  override fun toJson(writer: JsonWriter, value: T?, adapterContext: CompositeAdapterContext) {
    if (value == null) {
      writer.nullValue()
    } else {
      wrappedAdapter.toJson(writer, value, adapterContext)
    }
  }
}

class PresentCompositeAdapter(private val wrappedAdapter: CompositeAdapter) : CompositeAdapter> {
  override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): Optional.Present {
    return Optional.Present(wrappedAdapter.fromJson(reader, adapterContext))
  }

  override fun toJson(writer: JsonWriter, value: Optional.Present, adapterContext: CompositeAdapterContext) {
    wrappedAdapter.toJson(writer, value.value, adapterContext)
  }
}

class ApolloOptionalCompositeAdapter(private val wrappedAdapter: CompositeAdapter) : CompositeAdapter> {
  override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): Optional {
    return if (reader.peek() == JsonReader.Token.NULL) {
      reader.skipValue()
      Optional.Absent
    } else {
      Optional.Present(wrappedAdapter.fromJson(reader, adapterContext))
    }
  }

  override fun toJson(writer: JsonWriter, value: Optional, adapterContext: CompositeAdapterContext) {
    if (value is Optional.Present) {
      wrappedAdapter.toJson(writer, value.value, adapterContext)
    } else {
      writer.nullValue()
    }
  }
}

class AdapterToCompositeAdapter(private val wrappedAdapter: Adapter) : CompositeAdapter {
  override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): T {
    return wrappedAdapter.fromJson(reader, CustomScalarAdapters.Empty)
  }

  override fun toJson(writer: JsonWriter, value: T, adapterContext: CompositeAdapterContext) {
    wrappedAdapter.toJson(writer, CustomScalarAdapters.Empty, value)
  }
}

class ObjectCompositeAdapter(
    private val wrappedAdapter: CompositeAdapter,
    private val buffered: Boolean,
) : CompositeAdapter<@JvmSuppressWildcards T> {
  override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): T {
    val actualReader = if (buffered) {
      reader.buffer()
    } else {
      reader
    }
    actualReader.beginObject()
    return wrappedAdapter.fromJson(actualReader, adapterContext).also {
      actualReader.endObject()
    }
  }

  override fun toJson(writer: JsonWriter, value: T, adapterContext: CompositeAdapterContext) {
    if (buffered && writer !is MapJsonWriter) {
      /**
       * Convert to a Map first
       */
      val mapWriter = MapJsonWriter()
      mapWriter.beginObject()
      wrappedAdapter.toJson(mapWriter, value, adapterContext)
      mapWriter.endObject()

      /**
       * And write to the original writer
       */
      writer.writeAny(mapWriter.root()!!)
    } else {
      writer.beginObject()
      wrappedAdapter.toJson(writer, value, adapterContext)
      writer.endObject()
    }
  }
}

@JvmName("-nullable")
fun  CompositeAdapter.nullable() = NullableCompositeAdapter(this)

@JvmName("-list")
fun  CompositeAdapter.list() = ListCompositeAdapter(this)

@JvmName("-obj")
fun  CompositeAdapter.obj(buffered: Boolean = false) = ObjectCompositeAdapter(this, buffered)

@JvmName("-present")
fun  CompositeAdapter.present() = PresentCompositeAdapter(this)


@JvmName("-toJson")
@JvmOverloads
fun  CompositeAdapter.toJsonString(
    value: T,
    adapterContext: CompositeAdapterContext = CompositeAdapterContext.Builder().build(),
    indent: String? = null,
): String = buildJsonString(indent) {
  [email protected](this, value, adapterContext)
}

/**
 * Note that Arrays require their type to be known at compile time, so we construct an anonymous object with reference to
 * function with reified type parameters as a workaround.
 *
 */
@JvmName("-array2")
inline fun  CompositeAdapter.array() = object : CompositeAdapter> {

  private inline fun  arrayFromJson(wrappedAdapter: CompositeAdapter, reader: JsonReader, adapterContext: CompositeAdapterContext): Array {
    reader.beginArray()
    val list = mutableListOf()
    while (reader.hasNext()) {
      list.add(wrappedAdapter.fromJson(reader, adapterContext))
    }
    reader.endArray()
    return list.toTypedArray()
  }

  private inline fun  arrayToJson(
      wrappedAdapter: CompositeAdapter,
      writer: JsonWriter,
      value: Array,
      adapterContext: CompositeAdapterContext,
  ) {
    writer.beginArray()
    value.forEach {
      wrappedAdapter.toJson(writer, it, adapterContext)
    }
    writer.endArray()
  }

  override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): Array {
    return arrayFromJson(this@array, reader, adapterContext)
  }

  override fun toJson(writer: JsonWriter, value: Array, adapterContext: CompositeAdapterContext) {
    return arrayToJson(this@array, writer, value, adapterContext)
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy