forked from http4s/http4s
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
234 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
play-json/src/main/scala/org/http4s/play/PlayEntityCodec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package org.http4s.play | ||
|
||
object PlayEntityCodec extends PlayEntityDecoder with PlayEntityEncoder |
14 changes: 14 additions & 0 deletions
14
play-json/src/main/scala/org/http4s/play/PlayEntityDecoder.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.http4s.play | ||
|
||
import cats.effect.Sync | ||
import org.http4s.EntityDecoder | ||
import play.api.libs.json.Reads | ||
|
||
/** | ||
* Derive [[EntityDecoder]] if implicit [[Reads]] is in the scope without need to explicitly call `jsonOf` | ||
*/ | ||
trait PlayEntityDecoder { | ||
implicit def playEntityDecoder[F[_]: Sync, A: Reads]: EntityDecoder[F, A] = jsonOf[F, A] | ||
} | ||
|
||
object PlayEntityDecoder extends PlayEntityDecoder |
15 changes: 15 additions & 0 deletions
15
play-json/src/main/scala/org/http4s/play/PlayEntityEncoder.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.http4s.play | ||
|
||
import cats.Applicative | ||
import play.api.libs.json.Writes | ||
import org.http4s.EntityEncoder | ||
|
||
/** | ||
* Derive [[EntityEncoder]] if implicit [[Writes]] is in the scope without need to explicitly call `jsonEncoderOf` | ||
*/ | ||
trait PlayEntityEncoder { | ||
implicit def playEntityEncoder[F[_]: Applicative, A: Writes]: EntityEncoder[F, A] = | ||
jsonEncoderOf(EntityEncoder.stringEncoder[F], implicitly, implicitly) | ||
} | ||
|
||
object PlayEntityEncoder extends PlayEntityEncoder |
68 changes: 68 additions & 0 deletions
68
play-json/src/main/scala/org/http4s/play/PlayInstances.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package org.http4s.play | ||
|
||
import _root_.jawn.support.play.Parser.facade | ||
import cats.Applicative | ||
import cats.effect.Sync | ||
import fs2.Chunk | ||
import org.http4s.headers.`Content-Type` | ||
import org.http4s.{ | ||
DecodeResult, | ||
EntityDecoder, | ||
EntityEncoder, | ||
InvalidMessageBodyFailure, | ||
MediaType, | ||
Message, | ||
Uri, | ||
jawn | ||
} | ||
import play.api.libs.json._ | ||
|
||
trait PlayInstances { | ||
|
||
def jsonOf[F[_]: Sync, A](implicit decoder: Reads[A]): EntityDecoder[F, A] = | ||
jsonDecoder[F].flatMapR { json => | ||
decoder | ||
.reads(json) | ||
.fold( | ||
_ => | ||
DecodeResult.failure(InvalidMessageBodyFailure(s"Could not decode JSON: $json", None)), | ||
DecodeResult.success(_) | ||
) | ||
} | ||
|
||
implicit def jsonDecoder[F[_]: Sync]: EntityDecoder[F, JsValue] = | ||
jawn.jawnDecoder[F, JsValue] | ||
|
||
def jsonEncoderOf[F[_]: EntityEncoder[?[_], String]: Applicative, A: Writes] | ||
: EntityEncoder[F, A] = | ||
jsonEncoder[F].contramap[A](Json.toJson(_)) | ||
|
||
implicit def jsonEncoder[F[_]: Applicative]: EntityEncoder[F, JsValue] = | ||
EntityEncoder[F, Chunk[Byte]] | ||
.contramap[JsValue] { json => | ||
val bytes = json.toString.getBytes("UTF8") | ||
Chunk.bytes(bytes) | ||
} | ||
.withContentType(`Content-Type`(MediaType.application.json)) | ||
|
||
implicit val writesUri: Writes[Uri] = | ||
Writes.contravariantfunctorWrites.contramap[String, Uri](implicitly[Writes[String]], _.toString) | ||
|
||
implicit val readsUri: Reads[Uri] = | ||
implicitly[Reads[String]].flatMap { str => | ||
Uri | ||
.fromString(str) | ||
.fold( | ||
_ => | ||
new Reads[Uri] { | ||
def reads(json: JsValue): JsResult[Uri] = JsError("Invalid uri") | ||
}, | ||
Reads.pure(_) | ||
) | ||
} | ||
|
||
implicit class MessageSyntax[F[_]: Sync](self: Message[F]) { | ||
def decodeJson[A: Reads]: F[A] = | ||
self.as(implicitly, jsonOf[F, A]) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package org.http4s | ||
|
||
package object play extends PlayInstances |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package org.http4s | ||
package play.test // Get out of play package so we can import custom instances | ||
|
||
import _root_.play.api.libs.json._ | ||
import cats.effect.IO | ||
import cats.effect.laws.util.TestContext | ||
import org.http4s.headers.`Content-Type` | ||
import org.http4s.jawn.JawnDecodeSupportSpec | ||
import org.http4s.play._ | ||
|
||
// Originally based on CirceSpec | ||
class PlaySpec extends JawnDecodeSupportSpec[JsValue] { | ||
implicit val testContext = TestContext() | ||
|
||
testJsonDecoder(jsonDecoder) | ||
|
||
sealed case class Foo(bar: Int) | ||
val foo = Foo(42) | ||
implicit val format: OFormat[Foo] = Json.format[Foo] | ||
|
||
"json encoder" should { | ||
val json: JsValue = Json.obj("test" -> JsString("PlaySupport")) | ||
|
||
"have json content type" in { | ||
jsonEncoder.headers.get(`Content-Type`) must_== Some( | ||
`Content-Type`(MediaType.application.json)) | ||
} | ||
|
||
"write JSON" in { | ||
writeToString(json) must_== ("""{"test":"PlaySupport"}""") | ||
} | ||
|
||
} | ||
|
||
"jsonEncoderOf" should { | ||
"have json content type" in { | ||
jsonEncoderOf[IO, Foo].headers.get(`Content-Type`) must_== Some( | ||
`Content-Type`(MediaType.application.json)) | ||
} | ||
|
||
"write compact JSON" in { | ||
writeToString(foo)(jsonEncoderOf[IO, Foo]) must_== ("""{"bar":42}""") | ||
} | ||
|
||
} | ||
|
||
"jsonOf" should { | ||
"decode JSON from a Play decoder" in { | ||
val result = jsonOf[IO, Foo].decode( | ||
Request[IO]().withEntity(Json.obj("bar" -> JsNumber(42)): JsValue), | ||
strict = true) | ||
result.value.unsafeRunSync must_== Right(Foo(42)) | ||
} | ||
} | ||
|
||
"Uri codec" should { | ||
"round trip" in { | ||
// TODO would benefit from Arbitrary[Uri] | ||
val uri = Uri.uri("http://www.example.com/") | ||
|
||
Json.fromJson[Uri](Json.toJson(uri)).asOpt must_== (Some(uri)) | ||
} | ||
} | ||
|
||
"Message[F].decodeJson[A]" should { | ||
"decode json from a message" in { | ||
val req = Request[IO]().withEntity(Json.toJson(foo)) | ||
req.decodeJson[Foo] must returnValue(foo) | ||
} | ||
|
||
"fail on invalid json" in { | ||
val req = Request[IO]().withEntity(Json.toJson(List(13, 14))) | ||
req.decodeJson[Foo].attempt.unsafeRunSync must beLeft | ||
} | ||
} | ||
|
||
"PlayEntityCodec" should { | ||
"decode json without defining EntityDecoder" in { | ||
import org.http4s.play.PlayEntityDecoder._ | ||
val request = Request[IO]().withEntity(Json.obj("bar" -> JsNumber(42)): JsValue) | ||
val result = request.as[Foo] | ||
result.unsafeRunSync must_== Foo(42) | ||
} | ||
|
||
"encode without defining EntityEncoder using default printer" in { | ||
import org.http4s.play.PlayEntityEncoder._ | ||
writeToString(foo) must_== """{"bar":42}""" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
sbt.version=1.2.1 | ||
<<<<<<< HEAD | ||
|
||
======= | ||
>>>>>>> release-0.18.x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters