diff --git a/build.sbt b/build.sbt index d01a0b5..9a124c7 100644 --- a/build.sbt +++ b/build.sbt @@ -12,7 +12,7 @@ resolvers ++= Seq( ) libraryDependencies ++= { - val circeVersion = "0.5.2" + val circeVersion = "0.6.0" val akkaVersion = "2.4.8" Seq( diff --git a/src/main/scala/org/zalando/jsonapi/json/circe/CirceJsonapiDecoders.scala b/src/main/scala/org/zalando/jsonapi/json/circe/CirceJsonapiDecoders.scala index 73dcdc7..90c7b56 100644 --- a/src/main/scala/org/zalando/jsonapi/json/circe/CirceJsonapiDecoders.scala +++ b/src/main/scala/org/zalando/jsonapi/json/circe/CirceJsonapiDecoders.scala @@ -1,6 +1,5 @@ package org.zalando.jsonapi.json.circe -import cats.data.Xor import io.circe._ import org.zalando.jsonapi.json.FieldNames import org.zalando.jsonapi.model.JsonApiObject._ @@ -20,23 +19,23 @@ trait CirceJsonapiDecoders { }.toList) ) - implicit val valueDecoder = Decoder.instance[Value](_.as[Json].map(jsonToValue)) + implicit val valueDecoder = Decoder.instance[Value](_.as[Json].right.map(jsonToValue)) implicit val attributesDecoder = Decoder.instance[Attributes](hcursor ⇒ { - hcursor.as[Value].flatMap { + hcursor.as[Value].right.flatMap { case JsObjectValue(value) ⇒ - Xor.Right(value) + Right(value) case _ ⇒ - Xor.Left(DecodingFailure("only an object can be decoded to Attributes", hcursor.history)) + Left(DecodingFailure("only an object can be decoded to Attributes", hcursor.history)) } }) - implicit val attributeDecoder = Decoder.instance[Attribute](_.as[Attributes].map(_.head)) + implicit val attributeDecoder = Decoder.instance[Attribute](_.as[Attributes].right.map(_.head)) implicit val linksDecoder = Decoder.instance[Links](hcursor ⇒ { - hcursor.as[Value].flatMap { + hcursor.as[Value].right.flatMap { case JsObjectValue(attributes) ⇒ - Xor.Right(attributes.map { + Right(attributes.map { case Attribute(FieldNames.`self`, StringValue(url)) ⇒ Links.Self(url) case Attribute(FieldNames.`about`, StringValue(url)) ⇒ Links.About(url) @@ -49,22 +48,23 @@ trait CirceJsonapiDecoders { Links.Related(url) }) case _ ⇒ - Xor.Left(DecodingFailure("only an object can be decoded to Links", hcursor.history)) + Left(DecodingFailure("only an object can be decoded to Links", hcursor.history)) } }) - def jsonToData(json: Json): Xor[DecodingFailure, Data] = json match { + def jsonToData(json: Json): Either[DecodingFailure, Data] = json match { case json: Json if json.isArray ⇒ json.as[ResourceObjects] case json: Json if json.isObject ⇒ json.as[ResourceObject] } + implicit val dataDecoder = Decoder.instance[Data](_.as[Json].right.flatMap(jsonToData)) + implicit val relationshipDecoder = Decoder.instance[Relationship](hcursor ⇒ { for { - links ← hcursor.downField(FieldNames.`links`).as[Option[Links]] - // TODO: there's prolly a cleaner way here. there's a circular dependency Data -> ResourceObject(s) -> Relationship(s) -> Data that's giving circe problems - data ← hcursor.downField(FieldNames.`data`).as[Option[Json]].map(_.flatMap(jsonToData(_).toOption)) + links ← hcursor.downField(FieldNames.`links`).as[Option[Links]].right + data ← hcursor.downField(FieldNames.`data`).as[Option[Data]].right } yield Relationship( links = links, @@ -75,31 +75,31 @@ trait CirceJsonapiDecoders { implicit val relationshipsDecoder = Decoder.instance[Relationships](_.as[Map[String, Relationship]]) implicit val jsonApiDecoder = Decoder.instance[JsonApi](hcursor ⇒ { - hcursor.as[Value].flatMap { + hcursor.as[Value].right.flatMap { case JsObjectValue(attributes) ⇒ - Xor.Right(attributes.map { + Right(attributes.map { case Attribute(name, value) ⇒ JsonApiProperty(name, value) }) case _ ⇒ - Xor.Left(DecodingFailure("only an object can be decoded to JsonApi", hcursor.history)) + Left(DecodingFailure("only an object can be decoded to JsonApi", hcursor.history)) } }) implicit val metaDecoder = Decoder.instance[Meta](hcursor ⇒ { - hcursor.as[Value].flatMap { + hcursor.as[Value].right.flatMap { case JsObjectValue(attributes) ⇒ - Xor.Right(attributes.map { + Right(attributes.map { case Attribute(name, value) ⇒ name -> value }.toMap) case _ ⇒ - Xor.Left(DecodingFailure("only an object can be decoded to Meta", hcursor.history)) + Left(DecodingFailure("only an object can be decoded to Meta", hcursor.history)) } }) implicit val errorSourceDecoder = Decoder.instance[ErrorSource](hcursor ⇒ { for { - pointer ← hcursor.downField(FieldNames.`pointer`).as[Option[String]] - parameter ← hcursor.downField(FieldNames.`parameter`).as[Option[String]] + pointer ← hcursor.downField(FieldNames.`pointer`).as[Option[String]].right + parameter ← hcursor.downField(FieldNames.`parameter`).as[Option[String]].right } yield ErrorSource( pointer = pointer, @@ -109,14 +109,14 @@ trait CirceJsonapiDecoders { implicit val errorDecoder = Decoder.instance[Error](hcursor ⇒ { for { - id ← hcursor.downField(FieldNames.`id`).as[Option[String]] - status ← hcursor.downField(FieldNames.`status`).as[Option[String]] - code ← hcursor.downField(FieldNames.`code`).as[Option[String]] - title ← hcursor.downField(FieldNames.`title`).as[Option[String]] - detail ← hcursor.downField(FieldNames.`detail`).as[Option[String]] - links ← hcursor.downField(FieldNames.`links`).as[Option[Links]] - meta ← hcursor.downField(FieldNames.`meta`).as[Option[Meta]] - source ← hcursor.downField(FieldNames.`source`).as[Option[ErrorSource]] + id ← hcursor.downField(FieldNames.`id`).as[Option[String]].right + status ← hcursor.downField(FieldNames.`status`).as[Option[String]].right + code ← hcursor.downField(FieldNames.`code`).as[Option[String]].right + title ← hcursor.downField(FieldNames.`title`).as[Option[String]].right + detail ← hcursor.downField(FieldNames.`detail`).as[Option[String]].right + links ← hcursor.downField(FieldNames.`links`).as[Option[Links]].right + meta ← hcursor.downField(FieldNames.`meta`).as[Option[Meta]].right + source ← hcursor.downField(FieldNames.`source`).as[Option[ErrorSource]].right } yield Error( id = id, @@ -132,12 +132,12 @@ trait CirceJsonapiDecoders { implicit val resourceObjectDecoder = Decoder.instance[ResourceObject](hcursor ⇒ { for { - id ← hcursor.downField(FieldNames.`id`).as[Option[String]] - `type` ← hcursor.downField(FieldNames.`type`).as[String] - attributes ← hcursor.downField(FieldNames.`attributes`).as[Option[Attributes]] - relationships ← hcursor.downField(FieldNames.`relationships`).as[Option[Relationships]] - links ← hcursor.downField(FieldNames.`links`).as[Option[Links]] - meta ← hcursor.downField(FieldNames.`meta`).as[Option[Meta]] + id ← hcursor.downField(FieldNames.`id`).as[Option[String]].right + `type` ← hcursor.downField(FieldNames.`type`).as[String].right + attributes ← hcursor.downField(FieldNames.`attributes`).as[Option[Attributes]].right + relationships ← hcursor.downField(FieldNames.`relationships`).as[Option[Relationships]].right + links ← hcursor.downField(FieldNames.`links`).as[Option[Links]].right + meta ← hcursor.downField(FieldNames.`meta`).as[Option[Meta]].right } yield ResourceObject( id = id, @@ -150,20 +150,18 @@ trait CirceJsonapiDecoders { }) implicit val resourceObjectsDecoder = - Decoder.instance[ResourceObjects](_.as[List[ResourceObject]].map(ResourceObjects)) - - implicit val dataDecoder = Decoder.instance[Data](_.as[Json].flatMap(jsonToData)) + Decoder.instance[ResourceObjects](_.as[List[ResourceObject]].right.map(ResourceObjects)) - implicit val includedDecoder = Decoder.instance[Included](_.as[ResourceObjects].map(Included.apply)) + implicit val includedDecoder = Decoder.instance[Included](_.as[ResourceObjects].right.map(Included.apply)) implicit val rootObjectDecoder = Decoder.instance[RootObject](hcursor ⇒ { for { - data ← hcursor.downField(FieldNames.`data`).as[Option[Data]] - links ← hcursor.downField(FieldNames.`links`).as[Option[Links]] - errors ← hcursor.downField(FieldNames.`errors`).as[Option[Errors]] - meta ← hcursor.downField(FieldNames.`meta`).as[Option[Meta]] - included ← hcursor.downField(FieldNames.`included`).as[Option[Included]] - jsonapi ← hcursor.downField(FieldNames.`jsonapi`).as[Option[JsonApi]] + data ← hcursor.downField(FieldNames.`data`).as[Option[Data]].right + links ← hcursor.downField(FieldNames.`links`).as[Option[Links]].right + errors ← hcursor.downField(FieldNames.`errors`).as[Option[Errors]].right + meta ← hcursor.downField(FieldNames.`meta`).as[Option[Meta]].right + included ← hcursor.downField(FieldNames.`included`).as[Option[Included]].right + jsonapi ← hcursor.downField(FieldNames.`jsonapi`).as[Option[JsonApi]].right } yield RootObject( data = data, diff --git a/src/main/scala/org/zalando/jsonapi/json/circe/CirceJsonapiSupport.scala b/src/main/scala/org/zalando/jsonapi/json/circe/CirceJsonapiSupport.scala index bf786b3..90a3436 100644 --- a/src/main/scala/org/zalando/jsonapi/json/circe/CirceJsonapiSupport.scala +++ b/src/main/scala/org/zalando/jsonapi/json/circe/CirceJsonapiSupport.scala @@ -18,7 +18,7 @@ trait CirceJsonapiSupport extends CirceJsonapiEncoders with CirceJsonapiDecoders implicit val circeJsonapiUnmarshaller = Unmarshaller.delegate[String, RootObject]( `application/vnd.api+json`, `application/json` - )(decode[RootObject](_).toOption.get) + )(decode[RootObject](_).right.get) } object CirceJsonapiSupport extends CirceJsonapiSupport diff --git a/src/test/scala/org/zalando/jsonapi/json/circe/CirceJsonapiFormatSpec.scala b/src/test/scala/org/zalando/jsonapi/json/circe/CirceJsonapiFormatSpec.scala index eb08071..3388a29 100644 --- a/src/test/scala/org/zalando/jsonapi/json/circe/CirceJsonapiFormatSpec.scala +++ b/src/test/scala/org/zalando/jsonapi/json/circe/CirceJsonapiFormatSpec.scala @@ -9,8 +9,8 @@ import org.zalando.jsonapi.model._ class CirceJsonapiFormatSpec extends JsonBaseSpec[Json] with MustMatchers with CirceJsonapiEncoders with CirceJsonapiDecoders { - override protected def parseJson(jsonString: String): Json = parse(jsonString).toOption.get - protected def decodeJson[T](json: Json)(implicit d: io.circe.Decoder[T]): T = json.as[T].toOption.get + override protected def parseJson(jsonString: String): Json = parse(jsonString).right.get + protected def decodeJson[T](json: Json)(implicit d: io.circe.Decoder[T]): T = json.as[T].right.get "CirceJsonapiFormat" when { "serializing Jsonapi" must { diff --git a/version.sbt b/version.sbt index 5b60162..0512f16 100644 --- a/version.sbt +++ b/version.sbt @@ -1 +1 @@ -version in ThisBuild := "0.5.4" +version in ThisBuild := "0.6.0"