aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/scala/com/softwaremill/sttp/package.scala
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/scala/com/softwaremill/sttp/package.scala')
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/package.scala75
1 files changed, 34 insertions, 41 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala
index 459f13a..bb9c873 100644
--- a/core/src/main/scala/com/softwaremill/sttp/package.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/package.scala
@@ -1,13 +1,11 @@
package com.softwaremill
-import java.io.File
-import java.io.InputStream
-import java.nio.file.Path
-import java.nio.ByteBuffer
+import java.io.{File, InputStream}
import java.net.URI
+import java.nio.ByteBuffer
+import java.nio.file.Path
-import scala.annotation.{implicitNotFound, tailrec}
-import scala.io.Source
+import scala.annotation.implicitNotFound
import scala.language.higherKinds
package object sttp {
@@ -30,7 +28,7 @@ package object sttp {
- stream responses (sendStreamAndReceive?) / strict responses
- make sure response is consumed - only fire request when we know what to do with response?
- - reuse connections / connectio pooling - in handler
+ - reuse connections / connection pooling - in handler
- handler restriction? AnyHandler <: Handler Restriction
@@ -70,45 +68,34 @@ package object sttp {
val PATCH = Method("PATCH")
}
- trait ResponseBodyReader[T] {
- def fromInputStream(is: InputStream): T
- def fromBytes(bytes: Array[Byte]): T
- }
- object IgnoreResponseBody extends ResponseBodyReader[Unit] {
- override def fromInputStream(is: InputStream): Unit = {
- @tailrec def consume(): Unit = if (is.read() != -1) consume()
- consume()
- }
- override def fromBytes(bytes: Array[Byte]): Unit = {}
- }
- implicit object StringResponseBody extends ResponseBodyReader[String] {
- override def fromInputStream(is: InputStream): String = {
- Source.fromInputStream(is, "UTF-8").mkString
- }
- override def fromBytes(bytes: Array[Byte]): String = {
- new String(bytes, "UTF-8")
- }
- }
+ sealed trait ResponseAs[T]
+ object IgnoreResponse extends ResponseAs[Unit]
+ case class ResponseAsString(encoding: String) extends ResponseAs[String]
+ object ResponseAsByteArray extends ResponseAs[Array[Byte]]
+
+ case class ResponseAsStream[-S]()
- def responseAs[T](implicit r: ResponseBodyReader[T]): ResponseBodyReader[T] = r
- def ignoreResponseBody: ResponseBodyReader[Unit] = IgnoreResponseBody
+ def ignoreResponse: ResponseAs[Unit] = IgnoreResponse
+ def responseAsString(encoding: String): ResponseAs[String] = ResponseAsString(encoding)
+ def responseAsByteArray: ResponseAs[Array[Byte]] = ResponseAsByteArray
+ def responseAsStream[S]: ResponseAsStream[S] = ResponseAsStream[S]()
sealed trait RequestBody
- sealed trait SimpleRequestBody
+ sealed trait BasicRequestBody extends RequestBody
case object NoBody extends RequestBody
- case class StringBody(s: String) extends RequestBody with SimpleRequestBody
- case class ByteArrayBody(b: Array[Byte]) extends RequestBody with SimpleRequestBody
- case class ByteBufferBody(b: ByteBuffer) extends RequestBody with SimpleRequestBody
- case class InputStreamBody(b: InputStream) extends RequestBody with SimpleRequestBody
- case class InputStreamSupplierBody(b: () => InputStream) extends RequestBody with SimpleRequestBody
- case class FileBody(f: File) extends RequestBody with SimpleRequestBody
- case class PathBody(f: Path) extends RequestBody with SimpleRequestBody
+ case class StringBody(s: String) extends BasicRequestBody
+ case class ByteArrayBody(b: Array[Byte]) extends BasicRequestBody
+ case class ByteBufferBody(b: ByteBuffer) extends BasicRequestBody
+ case class InputStreamBody(b: InputStream) extends BasicRequestBody
+ case class InputStreamSupplierBody(b: () => InputStream) extends BasicRequestBody
+ case class FileBody(f: File) extends BasicRequestBody
+ case class PathBody(f: Path) extends BasicRequestBody
/**
* Use the factory methods `multiPart` to conveniently create instances of this class. A part can be then
* further customised using `fileName`, `contentType` and `header` methods.
*/
- case class MultiPart(name: String, data: RequestBody with SimpleRequestBody, fileName: Option[String] = None,
+ case class MultiPart(name: String, data: BasicRequestBody, fileName: Option[String] = None,
contentType: Option[String] = None, additionalHeaders: Map[String, String] = Map()) {
def fileName(v: String): MultiPart = copy(fileName = Some(v))
def contentType(v: String): MultiPart = copy(contentType = Some(v))
@@ -155,16 +142,22 @@ package object sttp {
def multipartData(parts: MultiPart*): RequestTemplate[U] = ???
- def send[R[_], T](responseReader: ResponseBodyReader[T])(
+ def send[R[_], T](responseAs: ResponseAs[T])(
implicit handler: SttpHandler[R], isRequest: IsRequest[U]): R[Response[T]] = {
- handler.send(this, responseReader)
+ handler.send(this, responseAs)
+ }
+
+ def send[R[_], S](responseAs: ResponseAsStream[S])(
+ implicit handler: SttpStreamHandler[R, S], isRequest: IsRequest[U]): R[Response[S]] = {
+
+ handler.send(this, responseAs)
}
- def sendStream[R[_], S, T](contentType: String, stream: S, responseReader: ResponseBodyReader[T])(
+ def sendStream[R[_], S, T](contentType: String, stream: S, responseAs: ResponseAs[T])(
implicit handler: SttpStreamHandler[R, S], isRequest: IsRequest[U]): R[Response[T]] = {
- handler.sendStream(this, contentType, stream, responseReader)
+ handler.sendStream(this, contentType, stream, responseAs)
}
}