Skip to content

Commit

Permalink
Merge pull request #631 from typelevel/topic/interface-rework
Browse files Browse the repository at this point in the history
Rework interfaces and implementations
  • Loading branch information
milessabin authored Jun 6, 2024
2 parents fe57582 + 8065ebf commit 379bb72
Show file tree
Hide file tree
Showing 23 changed files with 855 additions and 325 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ ThisBuild / scalaVersion := Scala2
ThisBuild / crossScalaVersions := Seq(Scala2, Scala3)
ThisBuild / tlJdkRelease := Some(11)

ThisBuild / tlBaseVersion := "0.19"
ThisBuild / tlBaseVersion := "0.20"
ThisBuild / startYear := Some(2019)
ThisBuild / licenses := Seq(License.Apache2)
ThisBuild / developers := List(
Expand Down
17 changes: 5 additions & 12 deletions modules/circe/src/main/scala/circemapping.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,15 @@ trait CirceMappingLike[F[_]] extends Mapping[F] {
else
DeferredCursor(path, (context, parent) => CirceCursor(context, value, Some(parent), env).success)

override def mkCursorForField(parent: Cursor, fieldName: String, resultName: Option[String]): Result[Cursor] = {
val context = parent.context
val fieldContext = context.forFieldOrAttribute(fieldName, resultName)
(typeMappings.fieldMapping(context, fieldName), parent.focus) match {
case (Some(CirceField(_, json, _)), _) =>
override def mkCursorForMappedField(parent: Cursor, fieldContext: Context, fm: FieldMapping): Result[Cursor] =
(fm, parent.focus) match {
case (CirceField(_, json, _), _) =>
CirceCursor(fieldContext, json, Some(parent), parent.env).success
case (Some(CursorFieldJson(_, f, _, _)), _) =>
case (CursorFieldJson(_, f, _, _), _) =>
f(parent).map(res => CirceCursor(fieldContext, focus = res, parent = Some(parent), env = parent.env))
case _ =>
super.mkCursorForField(parent, fieldName, resultName)
super.mkCursorForMappedField(parent, fieldContext, fm)
}
}

sealed trait CirceFieldMapping extends FieldMapping {
def subtree: Boolean = true
Expand Down Expand Up @@ -172,10 +169,6 @@ trait CirceMappingLike[F[_]] extends Mapping[F] {
else
Result.internalError(s"Focus ${focus} of static type $tpe cannot be narrowed to $subtpe")

def hasField(fieldName: String): Boolean =
tpe.hasField(fieldName) && focus.asObject.exists(_.contains(fieldName)) ||
typeMappings.fieldMapping(context, fieldName).isDefined

def field(fieldName: String, resultName: Option[String]): Result[Cursor] = {
val localField =
for {
Expand Down
15 changes: 2 additions & 13 deletions modules/core/src/main/scala/composedmapping.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,15 @@ import Cursor.AbstractCursor
import syntax._

abstract class ComposedMapping[F[_]](implicit val M: MonadThrow[F]) extends Mapping[F] {
override def mkCursorForField(parent: Cursor, fieldName: String, resultName: Option[String]): Result[Cursor] = {
val context = parent.context
val fieldContext = context.forFieldOrAttribute(fieldName, resultName)
typeMappings.fieldMapping(context, fieldName) match {
case Some(_) =>
ComposedCursor(fieldContext, parent.env).success
case _ =>
super.mkCursorForField(parent, fieldName, resultName)
}
}
override def mkCursorForMappedField(parent: Cursor, fieldContext: Context, fm: FieldMapping): Result[Cursor] =
ComposedCursor(fieldContext, parent.env).success

case class ComposedCursor(context: Context, env: Env) extends AbstractCursor {
val focus = null
val parent = None

def withEnv(env0: Env): Cursor = copy(env = env.add(env0))

override def hasField(fieldName: String): Boolean =
typeMappings.fieldMapping(context, fieldName).isDefined

override def field(fieldName: String, resultName: Option[String]): Result[Cursor] =
mkCursorForField(this, fieldName, resultName)
}
Expand Down
56 changes: 0 additions & 56 deletions modules/core/src/main/scala/cursor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ trait Cursor {
*/
def narrow(subtpe: TypeRef): Result[Cursor]

/** Does the value at this `Cursor` have a field named `fieldName`? */
def hasField(fieldName: String): Boolean

/**
* Yield a `Cursor` corresponding to the value of the field `fieldName` of the
* value at this `Cursor`, or an error on the left hand side if there is no
Expand All @@ -161,18 +158,6 @@ trait Cursor {
case _ => false
})

/**
* Does the possibly nullable value at this `Cursor` have a field named
* `fieldName`?
*/
def nullableHasField(fieldName: String): Boolean =
if (isNullable)
asNullable match {
case Result.Success(Some(c)) => c.nullableHasField(fieldName)
case _ => false
}
else hasField(fieldName)

/**
* Yield a `Cursor` corresponding to the value of the possibly nullable field
* `fieldName` of the value at this `Cursor`, or an error on the left hand
Expand All @@ -186,19 +171,6 @@ trait Cursor {
}
else field(fieldName, None)

/** Does the value at this `Cursor` have a field identified by the path `fns`? */
def hasPath(fns: List[String]): Boolean = fns match {
case Nil => true
case fieldName :: rest =>
nullableHasField(fieldName) && {
nullableField(fieldName) match {
case Result.Success(c) =>
!c.isList && c.hasPath(rest)
case _ => false
}
}
}

/**
* Yield a `Cursor` corresponding to the value of the field identified by path
* `fns` starting from the value at this `Cursor`, or an error on the left
Expand All @@ -213,28 +185,6 @@ trait Cursor {
}
}

/**
* Does the value at this `Cursor` generate a list along the path `fns`?
*
* `true` if `fns` is a valid path from the value at this `Cursor` and passes
* through at least one field with a list type.
*/
def hasListPath(fns: List[String]): Boolean = {
def loop(c: Cursor, fns: List[String], seenList: Boolean): Boolean = fns match {
case Nil => seenList
case fieldName :: rest =>
c.nullableHasField(fieldName) && {
c.nullableField(fieldName) match {
case Result.Success(c) =>
loop(c, rest, c.isList)
case _ => false
}
}
}

loop(this, fns, false)
}

/**
* Yield a list of `Cursor`s corresponding to the values generated by
* following the path `fns` from the value at this `Cursor`, or an error on
Expand Down Expand Up @@ -306,8 +256,6 @@ object Cursor {
def narrow(subtpe: TypeRef): Result[Cursor] =
Result.internalError(s"Focus ${focus} of static type $tpe cannot be narrowed to $subtpe")

def hasField(fieldName: String): Boolean = false

def field(fieldName: String, resultName: Option[String]): Result[Cursor] =
Result.internalError(s"No field '$fieldName' for type ${tpe.underlying}")
}
Expand Down Expand Up @@ -346,8 +294,6 @@ object Cursor {

def narrow(subtpe: TypeRef): Result[Cursor] = underlying.narrow(subtpe)

def hasField(fieldName: String): Boolean = underlying.hasField(fieldName)

def field(fieldName: String, resultName: Option[String]): Result[Cursor] = underlying.field(fieldName, resultName)
}

Expand Down Expand Up @@ -387,8 +333,6 @@ object Cursor {
def focus: Any = Result.internalError(s"Empty cursor has no focus")
def withEnv(env0: Env): DeferredCursor = copy(env = env.add(env0))

override def hasField(fieldName: String): Boolean = fieldName == deferredPath.head

override def field(fieldName: String, resultName: Option[String]): Result[Cursor] =
if(fieldName != deferredPath.head) Result.internalError(s"No field '$fieldName' for type ${tpe.underlying}")
else
Expand Down
7 changes: 2 additions & 5 deletions modules/core/src/main/scala/introspection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,12 @@ object Introspection {
case _ => None
}),
ValueField("interfaces", flipNullityDealias andThen {
case ot: ObjectType => Some(ot.interfaces.map(_.nullable))
case tf: TypeWithFields => Some(tf.interfaces.map(_.nullable))
case _ => None
}),
ValueField("possibleTypes", flipNullityDealias andThen {
case u: UnionType => Some(u.members.map(_.nullable))
case i: InterfaceType =>
Some(allTypes.collect {
case o: ObjectType if o.interfaces.exists(_ =:= i) => NullableType(o)
})
case i: InterfaceType => Some(targetSchema.implementations(i).map(_.nullable))
case _ => None
}),
ValueField("enumValues", flipNullityDealias andThen {
Expand Down
Loading

0 comments on commit 379bb72

Please sign in to comment.