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

marais.graphql.dsl.fields.kt Maven / Gradle / Ivy

package marais.graphql.dsl

import graphql.schema.DataFetcher
import kotlin.reflect.KFunction
import kotlin.reflect.KProperty1
import kotlin.reflect.KType
import kotlin.reflect.full.valueParameters
import kotlin.reflect.jvm.reflect

sealed class FieldSpec(val name: String, val description: String?) {

    /**
     * Field arguments as displayed in the schema, no special types
     */
    abstract val arguments: List

    /**
     * The code behind this field returning a value
     */
    abstract val dataFetcher: DataFetcher

    /**
     * The output type as shown in the schema (e.g. no async containers)
     */
    abstract val outputType: KType
}

class CustomFieldSpec(
    name: String,
    description: String?,
    override val outputType: KType,
    override val arguments: List,
    override val dataFetcher: DataFetcher
) : FieldSpec(name, description)

internal class SuspendLambdaFieldSpec(
    name: String,
    lambda: Function<*>,
    arity: Int,
    context: SchemaBuilderContext,
    receiver: Any? = null,
    reflected: KFunction<*> = lambda.reflect()!!
) : FieldSpec(name, context.takeDesc()) {

    override val outputType: KType = reflected.returnType.unwrapAsyncType()
    override val arguments: MutableList = mutableListOf(StaticArgument(lambda))

    init {
        reflected.valueParameters.mapTo(arguments) {
            it.createArgument(context)
        }
        context.checkRemainingArgDesc()
    }

    override val dataFetcher: DataFetcher =
        Lambdas.indirectCallSuspend(arity).fetcher(reflected.returnType, arguments, receiver, context)
}

internal class PropertyFieldSpec(
    property: KProperty1,
    name: String,
    receiver: R? = null,
    context: SchemaBuilderContext
) : FieldSpec(name, context.takeDesc() ?: property.extractDesc()) {

    override val dataFetcher: DataFetcher =
        property.getter.fetcher(property.returnType, emptyList(), receiver, context)
    override val outputType: KType = property.returnType.unwrapAsyncType()
    override val arguments: List = emptyList()
}

internal class FunctionFieldSpec(
    func: KFunction,
    name: String,
    receiver: R?,
    context: SchemaBuilderContext
) : FieldSpec(name, context.takeDesc() ?: func.extractDesc()) {

    override val outputType: KType = func.returnType.unwrapAsyncType()
    override val arguments: MutableList = mutableListOf()

    init {
        for (it in func.valueParameters) {
            arguments += it.createArgument(context)
        }
        context.checkRemainingArgDesc()
    }

    override val dataFetcher: DataFetcher = func.fetcher(func.returnType, arguments, receiver, context)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy