1 package io.circe
2 
3 import cats.data.{Validated, ValidatedNel}
4 import cats.syntax.either._
5 
6 trait ValidatingDecoder[A] extends Decoder[A] {
7   override def apply(cursor: HCursor): Decoder.Result[A] = decodeValidating(cursor).toEither.leftMap(_.head)
8 
9   override def decodeAccumulating(cursor: HCursor): Decoder.AccumulatingResult[A] = decodeValidating(cursor)
10 
11   def decodeValidating(cursor: HCursor): Decoder.AccumulatingResult[A]
12 }
13 
14 object ValidatingDecoder {
15   def instance[A](f: HCursor => Decoder.AccumulatingResult[A]): ValidatingDecoder[A] =
16     new ValidatingDecoder[A] {
17       override def decodeValidating(cursor: HCursor): Decoder.AccumulatingResult[A] = f(cursor)
18     }
19 
20   def lift[A, B](decoder: Decoder[A])(validate: A => ValidatedNel[String, B]): ValidatingDecoder[B] =
21     ValidatingDecoder.instance { cursor =>
22       Validated
23         .fromEither(decoder(cursor))
24         .toValidatedNel
25         .andThen(liftDecodingFailures[A, B](validate, cursor))
26     }
27 
28   private def liftDecodingFailures[A, B](
29       validate: A => ValidatedNel[String, B],
30       cursor: HCursor
31   ): A => ValidatedNel[DecodingFailure, B] = validate.andThen(_.leftMap(_.map(DecodingFailure(_, cursor.history))))
32 
33   def apply[A]: ApplyBuilder[A] = new ApplyBuilder[A]
34 
35   final class ApplyBuilder[A] {
36     def apply[B](validate: A => ValidatedNel[String, B])(implicit decoder: Decoder[A]): ValidatingDecoder[B] =
37       lift(decoder)(validate)
38   }
39 }
Line Stmt Id Pos Tree Symbol Code
7 11 197 - 230 Select cats.data.Validated.toEither ValidatingDecoder.this.decodeValidating(cursor).toEither
7 4 239 - 245 Select cats.data.NonEmptyList.head x$1.head
7 15 197 - 246 Apply cats.syntax.EitherOps.leftMap cats.syntax.`package`.either.catsSyntaxEither[cats.data.NonEmptyList[io.circe.DecodingFailure], A](ValidatingDecoder.this.decodeValidating(cursor).toEither).leftMap[io.circe.DecodingFailure](((x$1: cats.data.NonEmptyList[io.circe.DecodingFailure]) => x$1.head))
9 7 332 - 356 Apply io.circe.ValidatingDecoder.decodeValidating ValidatingDecoder.this.decodeValidating(cursor)
16 18 550 - 553 Apply io.circe.ValidatingDecoder.$anon.<init> new $anon()
17 5 663 - 672 Apply scala.Function1.apply f.apply(cursor)
21 12 786 - 970 Apply io.circe.ValidatingDecoder.instance ValidatingDecoder.instance[B](((cursor: io.circe.HCursor) => cats.data.Validated.fromEither[io.circe.DecodingFailure, A](decoder.apply(cursor)).toValidatedNel[io.circe.DecodingFailure, A].andThen[cats.data.NonEmptyList[io.circe.DecodingFailure], B](ValidatingDecoder.this.liftDecodingFailures[A, B](validate, cursor))))
23 10 861 - 876 Apply io.circe.Decoder.apply decoder.apply(cursor)
25 2 919 - 963 Apply io.circe.ValidatingDecoder.liftDecodingFailures ValidatingDecoder.this.liftDecodingFailures[A, B](validate, cursor)
25 14 831 - 964 Apply cats.data.Validated.andThen cats.data.Validated.fromEither[io.circe.DecodingFailure, A](decoder.apply(cursor)).toValidatedNel[io.circe.DecodingFailure, A].andThen[cats.data.NonEmptyList[io.circe.DecodingFailure], B](ValidatingDecoder.this.liftDecodingFailures[A, B](validate, cursor))
31 17 1127 - 1197 Apply scala.Function1.andThen validate.andThen[cats.data.Validated[cats.data.NonEmptyList[io.circe.DecodingFailure],B]](((x$2: cats.data.ValidatedNel[String,B]) => x$2.leftMap[cats.data.NonEmptyList[io.circe.DecodingFailure]](((x$3: cats.data.NonEmptyList[String]) => x$3.map[io.circe.DecodingFailure](((x$4: String) => DecodingFailure.apply(x$4, cursor.history)))))))
31 8 1154 - 1195 Apply cats.data.NonEmptyList.map x$3.map[io.circe.DecodingFailure](((x$4: String) => DecodingFailure.apply(x$4, cursor.history)))
31 16 1160 - 1194 Apply io.circe.DecodingFailure.apply DecodingFailure.apply(x$4, cursor.history)
31 3 1179 - 1193 Select io.circe.ACursor.history cursor.history
31 6 1144 - 1196 Apply cats.data.Validated.leftMap x$2.leftMap[cats.data.NonEmptyList[io.circe.DecodingFailure]](((x$3: cats.data.NonEmptyList[String]) => x$3.map[io.circe.DecodingFailure](((x$4: String) => DecodingFailure.apply(x$4, cursor.history)))))
33 9 1233 - 1252 Apply io.circe.ValidatingDecoder.ApplyBuilder.<init> new io.circe.ValidatingDecoder.ApplyBuilder[A]()
37 1 1403 - 1426 Apply io.circe.ValidatingDecoder.lift ValidatingDecoder.this.lift[A, B](decoder)(validate)