Skip to content

Commit

Permalink
Make all examples runnable using scala-cli
Browse files Browse the repository at this point in the history
  • Loading branch information
adamw committed Dec 19, 2024
1 parent 15d15b1 commit 820794c
Show file tree
Hide file tree
Showing 16 changed files with 80 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ core/native/local.sbt
.bsp/
.java-version
metals.sbt
.scala-build

.vscode

Expand Down
10 changes: 7 additions & 3 deletions core/src/main/scala/sttp/client4/ResponseException.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import scala.annotation.tailrec
* @tparam DE
* A deserialization-library-specific error type, describing the deserialization error in more detail.
*/
sealed abstract class ResponseException[+HE, +DE](error: String) extends Exception(error)
sealed abstract class ResponseException[+HE, +DE](error: String, cause: Option[Throwable])
extends Exception(error, cause.orNull)

/** Represents an http error, where the response was received successfully, but the status code is other than the
* expected one (typically other than 2xx).
Expand All @@ -28,15 +29,18 @@ sealed abstract class ResponseException[+HE, +DE](error: String) extends Excepti
* The type of the body to which the error response is deserialized.
*/
case class HttpError[+HE](body: HE, statusCode: StatusCode)
extends ResponseException[HE, Nothing](s"statusCode: $statusCode, response: $body")
extends ResponseException[HE, Nothing](s"statusCode: $statusCode, response: $body", None)

/** Represents an error that occured during deserialization of `body`.
*
* @tparam DE
* A deserialization-library-specific error type, describing the deserialization error in more detail.
*/
case class DeserializationException[+DE: ShowError](body: String, error: DE)
extends ResponseException[Nothing, DE](implicitly[ShowError[DE]].show(error))
extends ResponseException[Nothing, DE](
implicitly[ShowError[DE]].show(error),
if (error.isInstanceOf[Throwable]) Some(error.asInstanceOf[Throwable]) else None
)

object HttpError {
@tailrec def find(exception: Throwable): Option[HttpError[_]] =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// {cat=JSON; effects=ZIO; backend=HttpClient}: Receive & parse JSON using circe

//> using dep com.softwaremill.sttp.client4::circe:4.0.0-M20
//> using dep com.softwaremill.sttp.client4::zio:4.0.0-M20
//> using dep io.circe::circe-generic:0.14.10

package sttp.client4.examples

import io.circe.generic.auto.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
// {cat=Hello, World!; effects=Direct; backend=HttpClient}: Handle the body by both parsing it to JSON and returning the raw string

//> using dep com.softwaremill.sttp.client4::circe:4.0.0-M20
//> using dep io.circe::circe-generic:0.14.10

package sttp.client4.examples

import io.circe
import io.circe.generic.auto.*
import sttp.client4.*
import sttp.client4.circe.*
import sttp.client4.httpclient.HttpClientSyncBackend

@main def getRawResponseBodySynchronous(): Unit =
case class HttpBinResponse(origin: String, headers: Map[String, String])
Expand All @@ -13,7 +17,7 @@ import sttp.client4.httpclient.HttpClientSyncBackend
.get(uri"https://httpbin.org/get")
.response(asBoth(asJson[HttpBinResponse], asStringAlways))

val backend: SyncBackend = HttpClientSyncBackend()
val backend: SyncBackend = DefaultSyncBackend()

try
val response: Response[(Either[ResponseException[String, circe.Error], HttpBinResponse], String)] =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// {cat=Logging; effects=Direct; backend=HttpClient}: Add a logging backend wrapper, which uses slf4j

//> using dep com.softwaremill.sttp.client4::circe:4.0.0-M20
//> using dep com.softwaremill.sttp.client4::slf4j-backend:4.0.0-M20
//> using dep io.circe::circe-generic:0.14.10
//> using dep ch.qos.logback:logback-classic:1.5.13

package sttp.client4.examples

import io.circe.generic.auto.*
import sttp.client4.*
import sttp.client4.circe.*
import sttp.client4.httpclient.HttpClientSyncBackend
import sttp.client4.logging.LogConfig
import sttp.client4.logging.slf4j.Slf4jLoggingBackend

Expand All @@ -16,7 +22,7 @@ import sttp.client4.logging.slf4j.Slf4jLoggingBackend

val backend: SyncBackend =
Slf4jLoggingBackend(
HttpClientSyncBackend(),
DefaultSyncBackend(),
LogConfig(
includeTiming = true,
logRequestBody = false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// {cat=Hello, World!; effects=Direct; backend=HttpClient}: Post form data

//> using dep com.softwaremill.sttp.client4::core:4.0.0-M20

package sttp.client4.examples

import sttp.client4.*
import sttp.client4.httpclient.HttpClientSyncBackend

@main def postFormSynchronous(): Unit =
val signup = Some("yes")
Expand All @@ -12,7 +15,7 @@ import sttp.client4.httpclient.HttpClientSyncBackend
// use an optional parameter in the URI
.post(uri"https://httpbin.org/post?signup=$signup")

val backend = HttpClientSyncBackend()
val backend = DefaultSyncBackend()
val response = request.send(backend)

println(response.body)
Expand Down
4 changes: 4 additions & 0 deletions examples/src/main/scala/sttp/client4/examples/RetryZio.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// {cat=Resilience; effects=ZIO; backend=HttpClient}: Retry sending a request

//> using dep com.softwaremill.sttp.client4::zio:4.0.0-M20

package sttp.client4.examples

import sttp.client4.*
Expand Down
4 changes: 4 additions & 0 deletions examples/src/main/scala/sttp/client4/examples/StreamFs2.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// {cat=Streaming; effects=cats-effect; backend=HttpClient}: Stream request & response bodies using fs2

//> using dep com.softwaremill.sttp.client4::fs2:4.0.0-M20

package sttp.client4.examples

import cats.effect.ExitCode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// {cat=Streaming; effects=ZIO; backend=HttpClient}: Stream request & response bodies using ZIO-Streams

//> using dep com.softwaremill.sttp.client4::zio:4.0.0-M20

package sttp.client4.examples

import sttp.capabilities.zio.ZioStreams
Expand All @@ -11,7 +15,7 @@ import zio.stream.*

object StreamZio extends ZIOAppDefault:
def streamRequestBody: RIO[SttpClient, Unit] =
val stream: Stream[Throwable, Byte] = ZStream("Hello, world".getBytes.toIndexedSeq: _*)
val stream: Stream[Throwable, Byte] = ZStream("Hello, world".getBytes.toIndexedSeq*)
send(
basicRequest
.post(uri"https://httpbin.org/post")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// {cat=Testing}: Create a backend stub which simulates interactions using multiple query parameters

//> using dep com.softwaremill.sttp.client4::core:4.0.0-M20

package sttp.client4.examples

import sttp.client4.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// {cat=WebSocket; effects=Future; backend=Pekko}: Connect to & interact with a WebSocket

//> using dep com.softwaremill.sttp.client4::pekko-http-backend:4.0.0-M20
//> using dep org.apache.pekko::pekko-stream:1.1.2

package sttp.client4.examples

import sttp.client4._
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// {cat=WebSocket; effects=cats-effect; backend=HttpClient}: Connect to & interact with a WebSocket, using fs2 streaming

//> using dep com.softwaremill.sttp.client4::fs2:4.0.0-M20

package sttp.client4.examples

import cats.effect.ExitCode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// {cat=WebSocket; effects=Dir4ect; backend=HttpClient}: Connect to & interact with a WebSocket

//> using dep com.softwaremill.sttp.client4::core:4.0.0-M20

package sttp.client4.examples

import sttp.client4.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// {cat=WebSocket; effects=ZIO; backend=HttpClient}: Connect to & interact with a WebSocket

//> using dep com.softwaremill.sttp.client4::zio:4.0.0-M20

package sttp.client4.examples

import sttp.client4.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
// {cat=JSON; effects=Future; backend=Pekko}: Receive & parse JSON using json4s

//> using dep com.softwaremill.sttp.client4::json4s:4.0.0-M20
//> using dep com.softwaremill.sttp.client4::pekko-http-backend:4.0.0-M20
//> using dep org.json4s::json4s-native:4.0.7
//> using dep org.apache.pekko::pekko-stream:1.1.2

package sttp.client4.examples

import org.json4s.Formats
Expand All @@ -16,7 +23,7 @@ import scala.concurrent.Future
given Formats = org.json4s.DefaultFormats

val request = basicRequest
.get(uri"https://httpbin.org/get ")
.get(uri"https://httpbin.org/get")
.response(asJson[HttpBinResponse])

val backend: Backend[Future] = PekkoHttpBackend()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// {cat=WebSocket; effects=Direct; backend=HttpClient}: Connect to & interact with a WebSocket, using Ox channels for streaming

//> using dep com.softwaremill.sttp.client4::ox:4.0.0-M20

package sttp.client4.examples

import ox.*
Expand All @@ -13,7 +17,7 @@ import sttp.ws.WebSocketFrame
supervised:
val inputs = Source.fromValues(1, 2, 3).map(i => WebSocketFrame.text(s"Frame no $i"))
val (wsSource, wsSink) = asSourceAndSink(ws)
forkDiscard:
fork:
inputs.pipeTo(wsSink, propagateDone = true)
wsSource.foreach: frame =>
println(s"RECEIVED: $frame")
Expand Down

0 comments on commit 820794c

Please sign in to comment.