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 starts with some other string.
|
|
*
|
|
* @param key
|
|
* The key that should exist.
|
|
* @param prefix
|
|
* The substring that must be the prefix of the value.
|
|
*/
|
|
final class ValueStartsWith[F[_]: Functor: KeyValueProvider](
|
|
val key: String,
|
|
val prefix: String
|
|
) extends Predicate[F]:
|
|
|
|
/** @inheritDocs
|
|
*/
|
|
override def predicateType: String = ValueStartsWith.PredicateType
|
|
|
|
/** @inheritDocs
|
|
*/
|
|
override def eval(): F[Predicate.Result] =
|
|
KeyValueProvider[F].get(key).map {
|
|
case Some(value) => Predicate.Result(value.startsWith(prefix))
|
|
case _ => Predicate.Result.missed()
|
|
}
|
|
|
|
object ValueStartsWith:
|
|
|
|
final val PredicateType: String = "kv-string-starts-with"
|
|
|
|
def apply[F[_]: Functor: KeyValueProvider](
|
|
key: String,
|
|
prefix: String
|
|
): ValueStartsWith[F] =
|
|
new ValueStartsWith[F](key, prefix)
|
|
|
|
given valueStartsWithEncoder[F[_]]: Encoder[ValueStartsWith[F]] =
|
|
Encoder.instance[ValueStartsWith[F]] { p =>
|
|
Json.obj(
|
|
(JsonKeys.predicateType, Json.fromString(PredicateType)),
|
|
(JsonKeys.key, Json.fromString(p.key)),
|
|
(JsonKeys.value, Json.fromString(p.prefix))
|
|
)
|
|
}
|
|
|
|
given valueStartsWithDecoder[F[_]: Functor: KeyValueProvider]
|
|
: Decoder[ValueStartsWith[F]] =
|
|
Decoder.instance[ValueStartsWith[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 ValueStartsWith(key, value)
|
|
case candidate =>
|
|
Left(
|
|
DecodingFailure(
|
|
Messages.invalidPredicateType(candidate, PredicateType),
|
|
Nil
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
end ValueStartsWith
|