dev.constructive.eo.circe

Cross-representation optics bridging native Scala types and their circe-serialised form.

The entry point is JsonPrism.apply (aliased as codecPrism for the read-aloud API):

 val personPrism: JsonPrism[Person] = codecPrism[Person]
 val streetPrism: JsonPrism[String] =
   personPrism.field(_.address).field(_.street)
 streetPrism.modify(_.toUpperCase)(personJson)
 // → Ior.Right of the same Json, with .address.street upper-cased —
 //   no Person ever materialised.

Attributes

Members list

Type members

Classlikes

Structured failure surfaced by the default Ior-bearing surface of JsonPrism / JsonFieldsPrism / JsonTraversal / JsonFieldsTraversal.

Structured failure surfaced by the default Ior-bearing surface of JsonPrism / JsonFieldsPrism / JsonTraversal / JsonFieldsTraversal.

Every case carries a PathStep so the walk that produced the failure can point at the specific cursor position that refused. The default enum toString keeps the structural representation for testability; message gives a human-readable diagnostic.

Attributes

Companion
object
Source
JsonFailure.scala
Supertypes
trait Enum
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all
object JsonFailure

Attributes

Companion
enum
Source
JsonFailure.scala
Supertypes
trait Sum
trait Mirror
class Object
trait Matchable
class Any
Self type
object JsonPrism

Attributes

Companion
class
Source
JsonPrism.scala
Supertypes
class Object
trait Matchable
class Any
Self type
JsonPrism.type
final class JsonPrism[A] extends Optic[Json, Json, A, A, Affine], Dynamic

Specialised optic from io.circe.Json to native A.

Specialised optic from io.circe.Json to native A.

 JsonPrism[A]  Json)  // Fst = source (miss); Snd = single-walk writer

'''An Optional, not a Prism.''' A drilled focus lives INSIDE a document, so rebuilding needs the siblings — which a Prism's from(reverseGet) cannot see (it gets the focus alone). Carrying the source on the Affine seam fixes that at the carrier level: to captures a writer over the walk it already did, and from(Hit) applies it — so .modify / .replace preserve siblings whether called directly, upcast to Optic[…, Affine], or composed via andThen. Only the root full-cover prism is also a lawful Prism, and reverseGet stays for it. Mirrors dev.constructive.eo.avro.AvroRecordPrism.

Two call-surface tiers:

  • Default Ior-bearing: modify / get etc. accumulate Chain[JsonFailure]; partial success surfaces as Ior.Both(chain, inputJson).
  • *Unsafe: silent pass-through hot path.

Storage decomposition: a JsonPrism[A] holds a JsonFocus (Leaf vs Fields). The compatibility alias JsonFieldsPrism points back at this class so old code keeps compiling.

Attributes

Companion
object
Source
JsonPrism.scala
Supertypes
trait Dynamic
trait Optic[Json, Json, A, A, Affine]
class Object
trait Matchable
class Any

Macros backing JsonPrism.field(_.fieldName), selectDynamic, at(i), each, fields. Extracts the field name from the selector AST (same pattern as eo-generics' lens[S](_.field)) and emits a widenPath call.

Macros backing JsonPrism.field(_.fieldName), selectDynamic, at(i), each, fields. Extracts the field name from the selector AST (same pattern as eo-generics' lens[S](_.field)) and emits a widenPath call.

 val streetPrism: JsonPrism[String] =
   codecPrism[Person].field(_.address).field(_.street)

Attributes

Source
JsonPrismMacro.scala
Supertypes
class Object
trait Matchable
class Any
Self type
final class JsonTraversal[A] extends Dynamic

Multi-focus counterpart to JsonPrism: walks the JSON to some array, then applies the focus update to every element. Two pieces: prefix: Array[PathStep] (root-to-array, walked once) and focus: JsonFocus[A] (per-element). The Leaf-vs-Fields split lives in focus. Compat alias JsonFieldsTraversal points back here.

Multi-focus counterpart to JsonPrism: walks the JSON to some array, then applies the focus update to every element. Two pieces: prefix: Array[PathStep] (root-to-array, walked once) and focus: JsonFocus[A] (per-element). The Leaf-vs-Fields split lives in focus. Compat alias JsonFieldsTraversal points back here.

Two tiers (Ior-bearing default + *Unsafe), same shape as JsonPrism.

Attributes

Companion
object
Source
JsonTraversal.scala
Supertypes
trait Dynamic
class Object
trait Matchable
class Any
object JsonTraversal

Attributes

Companion
class
Source
JsonTraversal.scala
Supertypes
class Object
trait Matchable
class Any
Self type
enum PathStep

One step on a JsonPrism's flat navigation path — a field name or an array index.

One step on a JsonPrism's flat navigation path — a field name or an array index.

The path walker dispatches on the case to decide which of circe's representations to pierce: JsonObject for named fields, or the underlying Vector[Json] for array indices.

Public so users can read PathStep values off JsonFailure instances exposed by the default JsonPrism / JsonTraversal Ior-bearing surface.

Attributes

Source
PathStep.scala
Supertypes
trait Enum
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all

Types

type JsonFieldsPrism[A] = JsonPrism[A]

Compatibility alias for the multi-field Prism shape — a JsonPrism whose focus assembles A (a NamedTuple) from selected fields under a parent object. Same surface, same Optic supertype, same Ior diagnostics; the single- vs multi-field split lives in the internal JsonFocus. Kept so old type ascriptions keep compiling.

Compatibility alias for the multi-field Prism shape — a JsonPrism whose focus assembles A (a NamedTuple) from selected fields under a parent object. Same surface, same Optic supertype, same Ior diagnostics; the single- vs multi-field split lives in the internal JsonFocus. Kept so old type ascriptions keep compiling.

Attributes

Source
JsonFieldsPrism.scala

Compatibility alias for the multi-field Traversal shape — a JsonTraversal whose per-element focus assembles a NamedTuple from selected fields (the internal JsonFocus.Fields). Kept so old type ascriptions keep compiling.

Compatibility alias for the multi-field Traversal shape — a JsonTraversal whose per-element focus assembles a NamedTuple from selected fields (the internal JsonFocus.Fields). Kept so old type ascriptions keep compiling.

Attributes

Source
JsonFieldsTraversal.scala

Value members

Concrete methods

Root-level Prism from Json to a native type S. Alias for JsonPrism.apply that reads more naturally when composed with .field.

Root-level Prism from Json to a native type S. Alias for JsonPrism.apply that reads more naturally when composed with .field.

Attributes

Source
package.scala

Givens

Givens

A dev.constructive.eo.optics.Plated over the JSON tree itself — the immediate children of a node are an array's elements or an object's field values (a primitive has none). With it, Plated.transform / rewrite / universe walk a whole Json document recursively: redact every field at any depth, rewrite every string, round every number, rename keys throughout. Pure and total — rebuilding an array/object from new children needs no decode — and stack-safe via the cats.Eval trampoline in the combinators.

A dev.constructive.eo.optics.Plated over the JSON tree itself — the immediate children of a node are an array's elements or an object's field values (a primitive has none). With it, Plated.transform / rewrite / universe walk a whole Json document recursively: redact every field at any depth, rewrite every string, round every number, rename keys throughout. Pure and total — rebuilding an array/object from new children needs no decode — and stack-safe via the cats.Eval trampoline in the combinators.

 import dev.constructive.eo.circe.given
 import dev.constructive.eo.optics.Plated
 // Uppercase every string anywhere in the document:
 Plated.transform[Json](j => j.asString.fold(j)(s => Json.fromString(s.toUpperCase)))(doc)

Attributes

Source
package.scala