![JAR search and dependency download from the Maven repository](/logo.png)
caliban.schema.Step.scala Maven / Gradle / Ivy
package caliban.schema
import caliban.CalibanError.ExecutionError
import caliban.Value.NullValue
import caliban.execution.{ Field, FieldInfo }
import caliban.{ InputValue, PathValue, ResponseValue }
import zio.Cause
import zio.query.ZQuery
import zio.stacktracer.TracingImplicits.disableAutoTrace
import zio.stream.ZStream
sealed trait Step[-R]
object Step {
case class ListStep[-R](steps: List[Step[R]]) extends Step[R]
case class FunctionStep[-R](step: Map[String, InputValue] => Step[R]) extends Step[R]
case class MetadataFunctionStep[-R](step: Field => Step[R]) extends Step[R]
case class QueryStep[-R](query: ZQuery[R, Throwable, Step[R]]) extends Step[R]
case class StreamStep[-R](inner: ZStream[R, Throwable, Step[R]]) extends Step[R]
case class ObjectStep[-R](name: String, fields: String => Step[R]) extends Step[R]
object ObjectStep {
def apply[R](name: String, fields: Map[String, Step[R]]): ObjectStep[R] =
new ObjectStep[R](name, fields.getOrElse(_, NullStep))
}
object FailureStep {
def apply(error: Throwable): Step[Any] = QueryStep(ZQuery.failNow(error))
}
// PureStep is both a Step and a ReducedStep so it is defined outside this object
// This is to avoid boxing/unboxing pure values during step reduction
type PureStep = caliban.schema.PureStep
val PureStep: caliban.schema.PureStep.type = caliban.schema.PureStep
val NullStep: PureStep = PureStep(NullValue)
/**
* Create a Step that fails with the provided error
*/
def fail(error: Throwable): Step[Any] = FailureStep(error)
/**
* Create a Step that fails with the provided error message
*/
def fail(errorMessage: String): Step[Any] = FailureStep(ExecutionError(errorMessage))
/**
* Create a Step that either succeeds with the provided ResponseValue or fails with the provided error
*/
def fromEither(either: Either[Throwable, ResponseValue]): Step[Any] = either match {
case Right(value) => PureStep(value)
case Left(error) => FailureStep(error)
}
/**
* Merge 2 root steps. Root steps are supposed to be objects so we ignore other cases.
*/
def mergeRootSteps[R](step1: Step[R], step2: Step[R]): Step[R] = (step1, step2) match {
case (MetadataFunctionStep(l), MetadataFunctionStep(r)) => MetadataFunctionStep(f => mergeRootSteps(l(f), r(f)))
case (MetadataFunctionStep(l), r) => MetadataFunctionStep(f => mergeRootSteps(l(f), r))
case (l, MetadataFunctionStep(r)) => MetadataFunctionStep(f => mergeRootSteps(l, r(f)))
case (FunctionStep(l), FunctionStep(r)) => FunctionStep(args => mergeRootSteps(l(args), r(args)))
case (FunctionStep(l), r) => FunctionStep(args => mergeRootSteps(l(args), r))
case (l, FunctionStep(r)) => FunctionStep(args => mergeRootSteps(l, r(args)))
case (ObjectStep(name, fields1), ObjectStep(_, fields2)) => ObjectStep(name, mergeObjectSteps(fields1, fields2))
// if only step1 is an object, keep it
case (ObjectStep(_, _), _) => step1
// otherwise keep step2
case _ => step2
}
// fields2 override fields1 in case of conflict
private def mergeObjectSteps[R](fields1: String => Step[R], fields2: String => Step[R]): String => Step[R] =
(s: String) =>
fields2(s) match {
case NullStep => fields1(s)
case step => step
}
}
sealed abstract class ReducedStep[-R] { self =>
def isPure: Boolean
}
object ReducedStep {
final case class ListStep[-R](
steps: List[ReducedStep[R]],
areItemsNullable: Boolean,
isPure: Boolean
) extends ReducedStep[R]
final case class ObjectStep[-R](
fields: List[(String, ReducedStep[R], FieldInfo)],
hasPureFields: Boolean,
isPure: Boolean
) extends ReducedStep[R]
final case class QueryStep[-R](query: ZQuery[R, ExecutionError, ReducedStep[R]]) extends ReducedStep[R] {
final val isPure = false
}
final case class StreamStep[-R](inner: ZStream[R, ExecutionError, ReducedStep[R]]) extends ReducedStep[R] {
final val isPure = false
}
final case class DeferStep[-R](
obj: ReducedStep[R],
deferred: List[(ReducedStep[R], Option[String])],
path: List[PathValue]
) extends ReducedStep[R] {
final val isPure = false
}
object FailureStep {
def apply(error: Cause[ExecutionError]): ReducedStep[Any] = QueryStep(ZQuery.failCauseNow(error))
}
final case class DeferStreamStep[-R](
initial: ReducedStep[R],
remaining: StreamStep[R],
label: Option[String],
path: List[PathValue],
startFrom: Int
) extends ReducedStep[R] {
final val isPure = false
}
// PureStep is both a Step and a ReducedStep so it is defined outside this object
// This is to avoid boxing/unboxing pure values during step reduction
type PureStep = caliban.schema.PureStep
val PureStep: caliban.schema.PureStep.type = caliban.schema.PureStep
}
/**
* Represents the step of getting a pure response value without any effect.
* [[PureStep]] is both a [[Step]] and a [[ReducedStep]] to avoid boxing/unboxing pure values during step reduction.
*
* @param value the response value to return for that step
*/
final case class PureStep(value: ResponseValue) extends ReducedStep[Any] with Step[Any] {
final val isPure = true
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy