63 lines
1.7 KiB
Scala
63 lines
1.7 KiB
Scala
package gs.predicate.v0.json
|
|
|
|
import cats.Functor
|
|
import cats.syntax.all.*
|
|
import gs.predicate.v0.api.Messages
|
|
import gs.predicate.v0.api.Predicate
|
|
import gs.predicate.v0.serde.json.JsonKeys
|
|
import io.circe.Decoder
|
|
import io.circe.DecodingFailure
|
|
import io.circe.Encoder
|
|
import io.circe.Json
|
|
|
|
/** Predicate that matches if the JSON provider contains a JSON blob with the
|
|
* given key.
|
|
*
|
|
* @param key
|
|
* The name of the JSON value that should exist.
|
|
*/
|
|
final class JsonExists[F[_]: Functor: JsonProvider](
|
|
val key: String
|
|
) extends JsonPredicate[F]:
|
|
|
|
/** @inheritDocs
|
|
*/
|
|
final override val predicateType: String = JsonExists.PredicateType
|
|
|
|
/** @inheritDocs
|
|
*/
|
|
override def eval(): F[Predicate.Result] =
|
|
getJson(key).map(_.isDefined).map(Predicate.Result.apply)
|
|
|
|
object JsonExists:
|
|
|
|
final val PredicateType: String = "json-exists"
|
|
|
|
def apply[F[_]: Functor: JsonProvider](key: String): JsonExists[F] =
|
|
new JsonExists[F](key)
|
|
|
|
given jsonExistsEncoder[F[_]]: Encoder[JsonExists[F]] =
|
|
Encoder.instance[JsonExists[F]] { p =>
|
|
Json.obj(
|
|
(JsonKeys.predicateType, Json.fromString(PredicateType)),
|
|
(JsonKeys.key, Json.fromString(p.key))
|
|
)
|
|
}
|
|
|
|
given jsonExistsDecoder[F[_]: Functor: JsonProvider]: Decoder[JsonExists[F]] =
|
|
Decoder.instance[JsonExists[F]] { cursor =>
|
|
cursor.downField(JsonKeys.predicateType).as[String].flatMap {
|
|
case PredicateType =>
|
|
for key <- cursor.downField(JsonKeys.key).as[String]
|
|
yield new JsonExists(key)
|
|
case candidate =>
|
|
Left(
|
|
DecodingFailure(
|
|
Messages.invalidPredicateType(candidate, PredicateType),
|
|
Nil
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
end JsonExists
|