76 lines
2.2 KiB
Scala
76 lines
2.2 KiB
Scala
package gs.predicate.v0.kv
|
|
|
|
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 some [[KeyValueProvider]] contains the given key,
|
|
* and the string value associated with that key contains some other string.
|
|
*
|
|
* @param key
|
|
* The key that should exist.
|
|
* @param containedValue
|
|
* The substring that must be contained in the value.
|
|
*/
|
|
final class ValueContains[F[_]: Functor: KeyValueProvider](
|
|
val key: String,
|
|
val containedValue: String
|
|
) extends Predicate[F]:
|
|
|
|
/** @inheritDocs
|
|
*/
|
|
override def predicateType: String = ValueContains.PredicateType
|
|
|
|
/** @inheritDocs
|
|
*/
|
|
override def eval(): F[Predicate.Result] =
|
|
KeyValueProvider[F].get(key).map {
|
|
case Some(value) => Predicate.Result(value.contains(containedValue))
|
|
case _ => Predicate.Result.missed()
|
|
}
|
|
|
|
object ValueContains:
|
|
|
|
final val PredicateType: String = "kv-string-contains"
|
|
|
|
def apply[F[_]: Functor: KeyValueProvider](
|
|
key: String,
|
|
containedValue: String
|
|
): ValueContains[F] =
|
|
new ValueContains[F](key, containedValue)
|
|
|
|
given valueContainsEncoder[F[_]]: Encoder[ValueContains[F]] =
|
|
Encoder.instance[ValueContains[F]] { p =>
|
|
Json.obj(
|
|
(JsonKeys.predicateType, Json.fromString(PredicateType)),
|
|
(JsonKeys.key, Json.fromString(p.key)),
|
|
(JsonKeys.value, Json.fromString(p.containedValue))
|
|
)
|
|
}
|
|
|
|
given valueContainsDecoder[F[_]: Functor: KeyValueProvider]
|
|
: Decoder[ValueContains[F]] =
|
|
Decoder.instance[ValueContains[F]] { cursor =>
|
|
cursor.downField(JsonKeys.predicateType).as[String].flatMap {
|
|
case PredicateType =>
|
|
for
|
|
key <- cursor.downField(JsonKeys.key).as[String]
|
|
value <- cursor.downField(JsonKeys.value).as[String]
|
|
yield new ValueContains(key, value)
|
|
case candidate =>
|
|
Left(
|
|
DecodingFailure(
|
|
Messages.invalidPredicateType(candidate, PredicateType),
|
|
Nil
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
end ValueContains
|