com.softinio.verdict4s

Members list

Grouped members

No effect system

object SystemOne

Driving the protocol with no effect system at all.

Driving the protocol with no effect system at all.

verdict4s-core carries only cats-core, circe and Iron: no effect type, no HTTP client, no fs2. That is what this object is for. Render a request to JSON, send it with whatever HTTP client you already have, and parse the reply back into typed answers:

val body = SystemOne.render(request)
val text = myHttpClient.post(SystemOne.evaluateUrl, body) // your code
val evaluation = SystemOne.parse(text)

This is the path for Twitter Future, for Akka or Pekko HTTP, for sttp, and for a plain blocking client — anything without a lawful cats-effect instance. If you do have one, verdict4s-client is less work.

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
SystemOne.type

Errors

sealed abstract class Verdict4sError(message: String, cause: Option[Throwable] = ...) extends Exception

Failures a verdict4s call can produce.

Failures a verdict4s call can produce.

Lives in the effect-free core so that callers can pattern match on it without taking a dependency on cats-effect or http4s.

Attributes

Companion
object
Supertypes
class Exception
class Throwable
trait Serializable
class Object
trait Matchable
class Any
Show all
Known subtypes
class Api
class Decoding
class Invalid
class Transport
class Validation

Questions

final class Ask[Q <: Tuple]

A set of questions asked together, answered at exactly the right types.

A set of questions asked together, answered at exactly the right types.

One request carrying several questions is both cheaper and faster than one request each, and it is the shape the service is designed around. Ask keeps that batching while preserving each question's own answer type:

val (urgent, dept, mood) = client.ask(
 Ask(
   Question.noul("Does this convey urgency?"),
   Question.choice[Dept]("Which team should handle this?"),
   Question.score("How frustrated?", Seq("Calm", "Cross", "Livid"))
 ),
 state
)

urgent is a NoulAnswer, dept a ChoiceAnswer[Dept] and mood a ScoreAnswer -- destructured positionally, with no casts and no lookups by string. The map-based algebra.Evaluation remains available for cases where the questions are not known statically.

Question keys are generated positionally, so callers never name them. Use withKeys if you need them to match something else.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any

Configuration

trait Jitter[F[_]]

Where a retry delay's randomness comes from.

Where a retry delay's randomness comes from.

A two-method trait rather than a direct call to a random source, for two reasons. Tests get a fully deterministic schedule from Jitter.constant without a mocking library. And the obvious alternatives are both worse here: cats.effect.std.Random is only transitively on the classpath, and deriving randomness from Temporal.monotonic yields a constant on Scala.js, where the clock is millisecond-granular.

This lives in the client, not in algebra, because drawing a sample is an effect and the core must stay effect-free.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any
object Verdict4sEnv

Reading configuration from the environment. JVM only.

Reading configuration from the environment. JVM only.

A separate object rather than methods on Verdict4s, and not by preference: a Scala object cannot be split across src/ and src-jvm/, so adding these there would force default to be duplicated into both platform directories — exactly the drift that keeping one signature on both platforms is meant to prevent.

Scala.js has no environment to read, so this simply does not exist there. The JVM artifact having a slightly larger surface than the JS one is normal and does not affect Verdict4s.default.

Variable names match the official SDKs, so a project can share them.

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type

Client

object Verdict4s

Batteries-included entry point.

Batteries-included entry point.

Picks a sensible transport for whichever platform you are on — Ember on the JVM, the browser and Node Fetch API on Scala.js — so getting a working client is a one-liner:

Verdict4s.default[IO](apiKey).use { client =>
 client.ask(Ask(Question.noul("Is this urgent?")), ticket)
}

If you already have an http4s Client[F], or want a backend other than the default, depend on verdict4s-client and construct Verdict4sClient directly.

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
Verdict4s.type
final class Verdict4sClient[F[_]]

A client for the TypeSafe evaluation API.

A client for the TypeSafe evaluation API.

Takes an http4s Client[F] rather than building one. That single decision buys every backend and every platform without this library owning any of them — Ember, Fetch, Blaze, Netty, the JDK client — and it is why the test suite needs no network: Client.fromHttpApp serves routes in memory, so the same tests run on the JVM and on Node.

val client = Verdict4sClient[IO](httpClient, apiKey)

val (urgent, dept) = client.ask(
 Ask(
   Question.noul("Does this convey urgency?"),
   Question.choice[Dept]("Which team should handle this?")
 ),
 "Help! My payouts have been failing for 3 days."
)

Retries are on by default, matching the official SDKs; see algebra.RetryPolicy to tune or disable them.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any
object syntax

Optional sugar for the call site.

Optional sugar for the call site.

The documented form is client.ask(questions, state), which needs nothing in implicit scope and infers F from the client. This import adds a reading-order alternative for those who prefer it:

import com.softinio.verdict4s.syntax.*

given Verdict4sClient[IO] = client
val (urgent, dept) = Ask(q1, q2).run("payouts failing")

run needs the client as a given for F to be inferable, which is an unusual idiom; runWith is the same thing with the client passed explicitly.

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
syntax.type

Type members

Classlikes

object Ask

Building an Ask from one to twelve questions, and the type that computes its answers.

Building an Ask from one to twelve questions, and the type that computes its answers.

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Ask.type
object Jitter

Ready-made sources of jitter: a random one, and a constant one for tests.

Ready-made sources of jitter: a random one, and a constant one for tests.

Attributes

Companion
trait
Supertypes
class Object
trait Matchable
class Any
Self type
Jitter.type

Constructing a Verdict4sClient over a transport you supply.

Constructing a Verdict4sClient over a transport you supply.

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

The cases of Verdict4sError, and a constructor for API errors built from a raw response.

The cases of Verdict4sError, and a constructor for API errors built from a raw response.

Attributes

Companion
class
Supertypes
trait Sum
trait Mirror
class Object
trait Matchable
class Any
Self type