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

jvmMain.definitions.RaptorGraphArgumentDefinitionBuilder.kt Maven / Gradle / Ivy

The newest version!
package io.fluidsonic.raptor

import io.fluidsonic.graphql.*
import io.fluidsonic.raptor.graphql.internal.*
import io.fluidsonic.stdlib.*
import kotlin.reflect.*


@RaptorDsl
public class RaptorGraphArgumentDefinitionBuilder internal constructor(
	private val kotlinType: KotlinType,
	private val resolver: ArgumentResolver,
	private val stackTrace: List,
) {

	private var default: GValue? = null
	private val isMaybe = kotlinType.classifier == Maybe::class
	private var name: String? = null


	internal fun build() =
		GraphArgumentDefinition(
			defaultValue = default,
			description = null, // TODO
			kotlinType = kotlinType,
			name = name,
			resolver = resolver,
			stackTrace = stackTrace
		)


	@RaptorDsl
	private fun default(default: GValue) {
		check(!isMaybe) { "An optional argument of type '$kotlinType' cannot have a default value." }
		check(this.default === null) { "Cannot define multiple defaults." }

		this.default = default
	}


	// TODO refactor

	@RaptorDsl
	public fun defaultList() {
		default(GListValue(emptyList()))
	}


	@RaptorDsl
	public fun defaultNull() {
		default(GNullValue.withoutOrigin)
	}


	@RaptorDsl
	public fun defaultBoolean(default: Boolean) {
		default(GBooleanValue(default))
	}


	@RaptorDsl
	public fun defaultEnumValue(default: String) {
		default(GEnumValue(default))
	}


	@RaptorDsl
	public fun defaultFloat(default: Double) {
		default(GFloatValue(default))
	}


	@RaptorDsl
	public fun defaultInt(default: Int) {
		default(GIntValue(default))
	}


	@RaptorDsl
	public fun defaultString(default: String) {
		default(GStringValue(default))
	}


	@RaptorDsl
	public fun name(name: String) {
		check(this.name === null) { "Cannot define multiple names." }

		this.name = name
	}


	public interface Container {

		@RaptorDsl
		public fun  argument(
			type: KType,
			configure: RaptorGraphArgumentDefinitionBuilder.() -> Unit = {},
		): RaptorGraphArgumentDelegate
	}


	internal interface ContainerInternal : Container {

		fun add(argument: GraphArgumentDefinition)
	}


	internal class ContainerImpl(
		private val parentKotlinType: KotlinType, // TODO
		factoryName: String,
	) : ContainerInternal {

		val argumentDefinitions: MutableList = mutableListOf()
		val resolver = ArgumentResolver(factoryName = factoryName)


		override fun add(argument: GraphArgumentDefinition) {
			// TODO we need to evaluate all arguments lazily when the parent builder is done because provideDelegate won't be called yet and name is null
			if (argumentDefinitions.any { it.name === argument.name })
				error("Cannot define multiple arguments named '${argument.name}'.")

			argumentDefinitions += argument
		}


		@RaptorDsl
		override fun  argument(
			type: KType,
			configure: RaptorGraphArgumentDefinitionBuilder.() -> Unit,
		): RaptorGraphArgumentDelegate =
			RaptorGraphArgumentDefinitionBuilder(
				kotlinType = KotlinType.of(
					type = type,
					containingType = parentKotlinType,
					allowMaybe = true,
					allowNull = true,
					allowedVariance = KVariance.OUT,
					requireSpecialization = true
				),
				resolver = resolver,
				stackTrace = stackTrace(skipCount = 1)
			)
				.apply(configure)
				.build()
				.also(this::add)
				.let {
					@Suppress("UNCHECKED_CAST")
					it as RaptorGraphArgumentDelegate
				}


		@RaptorDsl
		internal fun  argument(
			type: KotlinType,
			configure: RaptorGraphArgumentDefinitionBuilder.() -> Unit,
		): RaptorGraphArgumentDelegate =
			RaptorGraphArgumentDefinitionBuilder(
				kotlinType = type,
				resolver = resolver,
				stackTrace = stackTrace(skipCount = 1)
			)
				.apply(configure)
				.build()
				.also(this::add)
				.let {
					@Suppress("UNCHECKED_CAST")
					it as RaptorGraphArgumentDelegate
				}
	}
}


@RaptorDsl
public inline fun  RaptorGraphArgumentDefinitionBuilder.Container.argument(
	noinline configure: RaptorGraphArgumentDefinitionBuilder.() -> Unit = {},
): RaptorGraphArgumentDelegate =
	argument(type = typeOf(), configure = configure)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy