implicit def readObjectAsList[V]()

in magenta-lib/src/main/scala/magenta/input/RiffRaffYamlReader.scala [14:43]


  implicit def readObjectAsList[V](implicit fmtv: Reads[V]) =
    new Reads[List[(String, V)]] {
      // copied from the map implementation in play.api.libs.json.Reads but builds an ordered
      // list instead of an unordered map
      def reads(json: JsValue): JsResult[List[(String, V)]] = json match {
        case JsObject(linkedMap) =>
          type Errors = scala.collection.Seq[
            (JsPath, scala.collection.Seq[JsonValidationError])
          ]
          def locate(e: Errors, key: String) = e.map { case (p, valerr) =>
            (JsPath \ key) ++ p -> valerr
          }

          linkedMap
            .foldLeft(Right(Nil): Either[Errors, List[(String, V)]]) {
              case (acc, (key, value)) =>
                (acc, Json.fromJson[V](value)(fmtv)) match {
                  case (Right(vs), JsSuccess(v, _)) => Right(vs :+ (key -> v))
                  case (Right(_), JsError(e))       => Left(locate(e, key))
                  case (Left(e), _: JsSuccess[_])   => Left(e)
                  case (Left(e1), JsError(e2)) => Left(e1 ++ locate(e2, key))
                }
            }
            .fold(JsError.apply, res => JsSuccess(res))
        case _ =>
          JsError(
            Seq(JsPath() -> Seq(JsonValidationError("error.expected.jsobject")))
          )
      }
    }