io.circe.Decoder.Result Scala Examples
The following examples show how to use io.circe.Decoder.Result.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: Analyzer.scala From scarango with MIT License | 8 votes |
package com.outr.arango import io.circe.Decoder.Result import io.circe.{Decoder, DecodingFailure, Encoder, HCursor, Json} sealed abstract class Analyzer(val name: String) object Analyzer { case object Identity extends Analyzer("identity") case object TextGerman extends Analyzer("text_de") case object TextEnglish extends Analyzer("text_en") case object TextSpanish extends Analyzer("text_es") case object TextFinnish extends Analyzer("text_fi") case object TextFrench extends Analyzer("text_fr") case object TextItalian extends Analyzer("text_it") case object TextDutch extends Analyzer("text_nl") case object TextNorwegian extends Analyzer("text_no") case object TextPortuguese extends Analyzer("text_pt") case object TextRussian extends Analyzer("text_ru") case object TextSwedish extends Analyzer("text_sv") case object TextChinese extends Analyzer("text_zh") private val map = List(Identity, TextGerman, TextEnglish, TextSpanish, TextFinnish, TextFrench, TextItalian, TextDutch, TextNorwegian, TextPortuguese, TextRussian, TextSwedish, TextChinese).map(a => a.name -> a).toMap def apply(name: String): Analyzer = map.getOrElse(name, throw new RuntimeException(s"Unable to find analyzer by name: $name")) implicit val decoder: Decoder[Analyzer] = new Decoder[Analyzer] { override def apply(c: HCursor): Result[Analyzer] = c.value.asString match { case Some(s) => Right(Analyzer(s)) case None => Left(DecodingFailure(s"Expected String to decode Analyzer, but got: ${c.value}", Nil)) } } implicit val encoder: Encoder[Analyzer] = new Encoder[Analyzer] { override def apply(a: Analyzer): Json = Json.fromString(a.name) } }
Example 2
Source File: APIWalTail.scala From scarango with MIT License | 5 votes |
package com.outr.arango.api import io.circe.Decoder.Result import io.youi.client.HttpClient import io.youi.http.{HeaderKey, HttpMethod} import io.youi.net._ import io.circe.{Decoder, DecodingFailure, HCursor} import profig.JsonUtil import scala.concurrent.{ExecutionContext, Future} object APIWalTail { private implicit def operationTypeDecoder: Decoder[OperationType] = new Decoder[OperationType] { override def apply(c: HCursor): Result[OperationType] = c.value.asNumber match { case Some(n) => Right(OperationType(n.toInt.get)) case None => Left(DecodingFailure(s"OperationType not a number: ${c.value}", Nil)) } } def get(client: HttpClient, global: Option[Boolean] = None, from: Option[Long] = None, to: Option[Long] = None, lastScanned: Long = 0L, chunkSize: Option[Long] = None, syncerId: Option[Long] = None, serverId: Option[Long] = None, clientId: Option[String] = None)(implicit ec: ExecutionContext): Future[WALOperations] = { client .method(HttpMethod.Get) .path(path"/_api/wal/tail", append = true) .param[Option[Long]]("from", from, None) .param[Option[Long]]("to", to, None) .param[Long]("lastScanned", lastScanned, 0L) .param[Option[Boolean]]("global", global, None) .param[Option[Long]]("chunkSize", chunkSize, None) .param[Option[Long]]("syncerId", syncerId, None) .param[Option[Long]]("serverId", serverId, None) .param[Option[String]]("clientId", clientId, None) .send() .map { response => val lines = response.content.map(_.asString).getOrElse("").split('\n').toList val operations = lines.map(_.trim).collect { case line if line.nonEmpty => JsonUtil.fromJsonString[WALOperation](line) } val headers = response.headers WALOperations( client = client, global = global, chunkSize = chunkSize, syncerId = syncerId, serverId = serverId, clientId = clientId, checkMore = headers.first(HeaderKey("X-Arango-Replication-Checkmore")).exists(_.toBoolean), fromPresent = headers.first(HeaderKey("X-Arango-Replication-Frompresent")).exists(_.toBoolean), lastIncluded = headers.first(HeaderKey("X-Arango-Replication-Lastincluded")).map(_.toLong).getOrElse(-1L), lastScanned = headers.first(HeaderKey("X-Arango-Replication-Lastscanned")).map(_.toLong).getOrElse(-1L), lastTick = headers.first(HeaderKey("X-Arango-Replication-Lasttick")).map(_.toLong).getOrElse(-1L), operations = operations ) } } }
Example 3
Source File: TransactionStatus.scala From scarango with MIT License | 5 votes |
package com.outr.arango.transaction import io.circe.Decoder.Result import io.circe.{Decoder, DecodingFailure, HCursor} sealed trait TransactionStatus object TransactionStatus { case object Running extends TransactionStatus case object Committed extends TransactionStatus case object Aborted extends TransactionStatus implicit val decoder: Decoder[TransactionStatus] = new Decoder[TransactionStatus] { override def apply(c: HCursor): Result[TransactionStatus] = c.value.asString match { case Some(s) => Right(TransactionStatus(s)) case None => Left(DecodingFailure(s"Failed to decode from ${c.value}", Nil)) } } def apply(value: String): TransactionStatus = value match { case "running" => Running case "committed" => Committed case "aborted" => Aborted } }
Example 4
Source File: Transaction.scala From scarango with MIT License | 5 votes |
package com.outr.arango.transaction import com.outr.arango.Graph import io.circe.Decoder.Result import io.circe.{Decoder, DecodingFailure, HCursor} import scala.concurrent.{ExecutionContext, Future} case class Transaction(id: String, status: TransactionStatus) { private[arango] var graph: Option[Graph] = None def withGraph(option: Option[Graph]): Transaction = { graph = option this } def checkStatus()(implicit ec: ExecutionContext): Future[Transaction] = { val g = graph.getOrElse(throw new RuntimeException("Graph not included!")) g.arangoDatabase.transactionStatus(id).map(_.withGraph(graph)) } def commit()(implicit ec: ExecutionContext): Future[Unit] = { val g = graph.getOrElse(throw new RuntimeException("Graph not included!")) g.arangoDatabase.transactionCommit(id).map { t => t.status match { case TransactionStatus.Running => throw new RuntimeException("Commit failed, transaction still running!") case TransactionStatus.Committed => () case TransactionStatus.Aborted => throw new RuntimeException("Commit failed, transaction aborted!") } } } def abort()(implicit ec: ExecutionContext): Future[Unit] = { val g = graph.getOrElse(throw new RuntimeException("Graph not included!")) g.arangoDatabase.transactionAbort(id).map { t => t.status match { case TransactionStatus.Running => throw new RuntimeException("Abort failed, transaction still running!") case TransactionStatus.Committed => throw new RuntimeException("Abort failed, transaction committed!") case TransactionStatus.Aborted => () } } } }
Example 5
Source File: Serialization.scala From scarango with MIT License | 5 votes |
package com.outr.arango import io.circe.Decoder.Result import io.circe.{Decoder, Encoder, HCursor, Json} import scala.language.experimental.macros case class Serialization[D](private val doc2Json: D => Json, private val json2Doc: Json => D) { final def toJson(document: D): Json = Id.update(doc2Json(document)) final def fromJson(json: Json): D = json2Doc(Id.update(json)) lazy val decoder: Decoder[D] = new Decoder[D] { override def apply(c: HCursor): Result[D] = Right(fromJson(c.value)) } } object Serialization { def auto[D]: Serialization[D] = macro Macros.serializationAuto[D] def create[D](encoder: Encoder[D], decoder: Decoder[D]): Serialization[D] = { val doc2Json = (d: D) => encoder(d) val json2Doc = (json: Json) => decoder.decodeJson(json) match { case Left(df) => throw df case Right(d) => d } Serialization[D](doc2Json, json2Doc) } }
Example 6
package com.outr.arango import io.circe.Decoder.Result import io.circe.{Decoder, Encoder, HCursor, Json} import com.outr.arango.JsonImplicits._ lazy val _id: String = s"$collection/$value" override def compare(that: Id[D]): Int = this._id.compare(that._id) override def toString: String = _id } object Id { private val ExtractorRegex = """(.+)/(.+)""".r implicit def encoder[D]: Encoder[Id[D]] = new Encoder[Id[D]] { override def apply(id: Id[D]): Json = Json.fromString(id._id) } implicit def decoder[D]: Decoder[Id[D]] = new Decoder[Id[D]] { override def apply(c: HCursor): Result[Id[D]] = c.value.asString.get match { case ExtractorRegex(collection, value) => Right(Id[D](value, collection)) } } def parse[D](id: String): Id[D] = id match { case ExtractorRegex(collection, value) => Id[D](value, collection) } def extract[D](json: Json): Id[D] = { val updated = update(json) decoder[D].decodeJson((updated \ "_id").get) match { case Left(df) => throw df case Right(id) => id } } def update(json: Json): Json = { val _key = (json \ "_key").flatMap(_.asString) val _id = (json \ "_id").flatMap(_.asString) val _identity = _id.map(parse[Any]) if (_id.nonEmpty && _key.isEmpty) { json.deepMerge(Json.obj("_key" -> Json.fromString(_identity.get.value))) } else { json } } }
Example 7
Source File: package.scala From kanadi with MIT License | 5 votes |
package org.zalando import java.net.URI import cats.syntax.either._ import io.circe.Decoder.Result import io.circe.syntax._ import io.circe.{Decoder, DecodingFailure, Encoder, HCursor} import scala.util.control.NonFatal package object kanadi { private[kanadi] implicit val uriEncoder: Encoder[URI] = Encoder.instance[URI](_.toString.asJson) private[kanadi] implicit val uriDecoder: Decoder[URI] = new Decoder[URI] { override def apply(c: HCursor): Result[URI] = c.as[String].flatMap { value => try { Right(new URI(value)) } catch { case NonFatal(_) => Left(DecodingFailure("Invalid Uri", c.history)) } } } }
Example 8
Source File: SimpleAuthEnum.scala From tsec with MIT License | 5 votes |
package tsec.authorization import cats.{Eq, MonadError} import cats.syntax.all._ import io.circe.Decoder.Result import io.circe._ import io.circe.syntax._ import tsec.common.TSecError import scala.reflect.ClassTag private def codecFromRepr(r: Repr): Either[DecodingFailure, T] = { val ix = ixFromRepr(r) if (ix >= 0) Right(values(ix)) else Left(cachedDecodingFailure) } implicit lazy val decoder: Decoder[T] = new Decoder[T] { def apply(c: HCursor): Result[T] = c.as[Repr].flatMap(codecFromRepr) } implicit lazy val encoder: Encoder[T] = new Encoder[T] { def apply(a: T): Json = getRepr(a).asJson } } object SimpleAuthEnum { type InvalidAuthorization = InvalidAuthorization.type case object InvalidAuthorization extends TSecError { def cause: String = "Invalid Authorization" } }
Example 9
Source File: package.scala From tsec with MIT License | 5 votes |
package tsec import io.circe.{Printer, _} import io.circe.syntax._ import cats.implicits._ import io.circe.Decoder.Result package object jwt { val JWTPrinter = Printer(true, "") sealed trait JWTAudience { def toList: List[String] } case class JWTSingleAudience(value: String) extends JWTAudience { def toList = List(value) } case class JWTListAudience(values: List[String]) extends JWTAudience { def toList = values } implicit val audienceDecoder: Decoder[JWTAudience] = new Decoder[JWTAudience] { def apply(c: HCursor): Result[JWTAudience] = c.as[String] match { case Right(a) => Right(JWTSingleAudience(a)) case _ => c.as[List[String]].map(JWTListAudience(_)) } } implicit val audienceEncoder: Encoder[JWTAudience] = new Encoder[JWTAudience] { def apply(a: JWTAudience): Json = a match { case JWTSingleAudience(value) => value.asJson case JWTListAudience(values) => values.asJson } } }
Example 10
Source File: Measurement.scala From temperature-machine with Apache License 2.0 | 5 votes |
package bad.robot.temperature import bad.robot.temperature.rrd.{Host, Seconds} import io.circe.Decoder.Result import io.circe._ object Measurement { implicit def jsonEncoder: Encoder[Measurement] = new Encoder[Measurement] { def apply(measurement: Measurement): Json = Json.obj( ("host", Encoder[Host].apply(measurement.host)), ("seconds", Json.fromLong(measurement.time.value)), ("sensors", Encoder[List[SensorReading]].apply(measurement.temperatures)) ) } implicit def jsonDecoder: Decoder[Measurement] = new Decoder[Measurement] { override def apply(cursor: HCursor): Result[Measurement] = for { host <- cursor.get[Host]("host") seconds <- cursor.get[Long]("seconds") sensors <- cursor.get[List[SensorReading]]("sensors") } yield Measurement(host, Seconds(seconds), sensors) } } case class Measurement(host: Host, time: Seconds, temperatures: List[SensorReading])
Example 11
Source File: SessionManager.scala From pizza-auth-3 with MIT License | 5 votes |
package moe.pizza.auth.webapp import java.time.Instant import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule import moe.pizza.auth.interfaces.UserDatabase import moe.pizza.auth.webapp.SessionManager._ import moe.pizza.auth.webapp.Types.{HydratedSession, Session, Session2} import org.http4s.{HttpService, _} import org.http4s.server._ import org.slf4j.LoggerFactory import pdi.jwt.{JwtAlgorithm, JwtCirce, JwtClaim} import io.circe.generic.auto._ import Utils._ import io.circe.Decoder.Result import scala.util.Try object SessionManager { val HYDRATEDSESSION = AttributeKey[HydratedSession]("HYDRATEDSESSION") val LOGOUT = AttributeKey[String]("LOGOUT") val COOKIESESSION = "authsession" } class SessionManager(secretKey: String, ud: UserDatabase) extends HttpMiddleware { val log = LoggerFactory.getLogger(getClass) val OM = new ObjectMapper() OM.registerModule(DefaultScalaModule) case class MyJwt(exp: Long, iat: Long, session: String) implicit def toOption[A](e: Result[A]): Option[A] = { e match { case Left(_) => None case Right(a) => Some(a) } } override def apply(s: HttpService): HttpService = Service.lift { req => log.info(s"Intercepting request ${req}") // TODO: this used to be nice with toOption, what happened val sessions = req.headers.get(headers.Cookie).toList.flatMap(_.values.list).flatMap { header => JwtCirce.decodeJson(header.content, secretKey, Seq(JwtAlgorithm.HS256)) .toOption .flatMap { jwt => jwt.as[MyJwt] match { case Right(x) => Some(x) case Left(_) => None } } .flatMap { myjwt => Try { OM.readValue(myjwt.session, classOf[Session2]) }.toOption } } log.info(s"found sessions: ${sessions}") // if we didn't find a valid session, make them one val session = sessions.headOption.getOrElse(Session2(List.empty, None, None, None)) // do the inner request val hydrated = session.hydrate(ud) log.info(s"running inner router with hydrated session ${hydrated}") val response = s(req.copy(attributes = req.attributes.put(HYDRATEDSESSION, hydrated))) response.map { resp => // do all of this once the request has been created val sessionToSave = resp.attributes .get(HYDRATEDSESSION) .map(_.dehydrate()) .getOrElse(session) val oldsessions = resp.headers .get(headers.Cookie) .toList .flatMap(_.values.list) .filter(_.name == COOKIESESSION) if (resp.attributes.get(LOGOUT).isEmpty) { log.info(s"saving the session as a cookie") val claim = JwtClaim( expiration = Some( Instant.now .plusSeconds(86400 * 30) .getEpochSecond), // lasts 30 days issuedAt = Some(Instant.now.getEpochSecond) ) + ("session", OM.writeValueAsString(sessionToSave)) val token = JwtCirce.encode(claim, secretKey, JwtAlgorithm.HS256) resp.addCookie( new Cookie(COOKIESESSION, token, None, None, None, path = Some("/")) ) } else { log.info(s"log out flag was set, not saving any cookies") resp.removeCookie(COOKIESESSION) } } } }
Example 12
Source File: IamIdentitiesClient.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.storage import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.http.scaladsl.client.RequestBuilding.Get import akka.http.scaladsl.model.HttpRequest import akka.http.scaladsl.model.headers.OAuth2BearerToken import akka.http.scaladsl.unmarshalling.FromEntityUnmarshaller import akka.util.ByteString import cats.effect.{ContextShift, Effect, IO} import cats.implicits._ import ch.epfl.bluebrain.nexus.rdf.implicits._ import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClient.Identity._ import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClient._ import ch.epfl.bluebrain.nexus.storage.IamIdentitiesClientError.IdentitiesSerializationError import ch.epfl.bluebrain.nexus.storage.config.IamClientConfig import de.heikoseeberger.akkahttpcirce.ErrorAccumulatingCirceSupport.{DecodingFailures => AccDecodingFailures} import io.circe.Decoder.Result import io.circe.{Decoder, DecodingFailure, HCursor} import scala.concurrent.ExecutionContext class IamIdentitiesClient[F[_]](config: IamClientConfig)(implicit F: Effect[F], as: ActorSystem) extends JsonLdCirceSupport { private val um: FromEntityUnmarshaller[Caller] = unmarshaller[Caller] implicit private val ec: ExecutionContext = as.dispatcher implicit private val contextShift: ContextShift[IO] = IO.contextShift(ec) def apply()(implicit credentials: Option[AccessToken]): F[Caller] = credentials match { case Some(token) => execute(Get(config.identitiesIri.asAkka).addCredentials(OAuth2BearerToken(token.value))) case None => F.pure(Caller.anonymous) } private def execute(req: HttpRequest): F[Caller] = { IO.fromFuture(IO(Http().singleRequest(req))).to[F].flatMap { resp => if (resp.status.isSuccess()) IO.fromFuture(IO(um(resp.entity))).to[F].recoverWith { case err: AccDecodingFailures => F.raiseError(IdentitiesSerializationError(err.getMessage)) case err: Error => F.raiseError(IdentitiesSerializationError(err.getMessage)) } else IO.fromFuture(IO(resp.entity.dataBytes.runFold(ByteString(""))(_ ++ _).map(_.utf8String))) .to[F] .flatMap { err => F.raiseError(IamIdentitiesClientError.unsafe(resp.status, err)) } } } } object IamIdentitiesClient { final case class Authenticated(realm: String) extends Identity private def decodeAnonymous(hc: HCursor): Result[Subject] = hc.get[String]("@type").flatMap { case "Anonymous" => Right(Anonymous) case _ => Left(DecodingFailure("Cannot decode Anonymous Identity", hc.history)) } private def decodeUser(hc: HCursor): Result[Subject] = (hc.get[String]("subject"), hc.get[String]("realm")).mapN { case (subject, realm) => User(subject, realm) } private def decodeGroup(hc: HCursor): Result[Identity] = (hc.get[String]("group"), hc.get[String]("realm")).mapN { case (group, realm) => Group(group, realm) } private def decodeAuthenticated(hc: HCursor): Result[Identity] = hc.get[String]("realm").map(Authenticated) private val attempts = List[HCursor => Result[Identity]](decodeAnonymous, decodeUser, decodeGroup, decodeAuthenticated) implicit val identityDecoder: Decoder[Identity] = Decoder.instance { hc => attempts.foldLeft(Left(DecodingFailure("Unexpected", hc.history)): Result[Identity]) { case (acc @ Right(_), _) => acc case (_, f) => f(hc) } } } }
Example 13
Source File: ValueEnumWithUnknown.scala From AckCord with MIT License | 5 votes |
package ackcord.util import enumeratum.values.{IntEnum, IntEnumEntry, StringEnum, StringEnumEntry, ValueEnum, ValueEnumEntry} import io.circe.Decoder.Result import io.circe._ trait ValueEnumWithUnknown[ValueType, EntryType <: ValueEnumEntry[ValueType]] { self: ValueEnum[ValueType, EntryType] => def createUnknown(value: ValueType): EntryType } trait IntCirceEnumWithUnknown[EntryType <: IntEnumEntry] extends IntEnum[EntryType] with ValueEnumWithUnknown[Int, EntryType] { self => implicit val codec: Codec[EntryType] = new Codec[EntryType] { private val valueEncoder = implicitly[Encoder[Int]] private val valueDecoder = implicitly[Decoder[Int]] def apply(a: EntryType): Json = valueEncoder.apply(a.value) def apply(c: HCursor): Result[EntryType] = valueDecoder.apply(c).map(v => withValueOpt(v).getOrElse(createUnknown(v))) } } trait StringCirceEnumWithUnknown[EntryType <: StringEnumEntry] extends StringEnum[EntryType] with ValueEnumWithUnknown[String, EntryType] { self => implicit val codec: Codec[EntryType] = new Codec[EntryType] { private val valueEncoder = implicitly[Encoder[String]] private val valueDecoder = implicitly[Decoder[String]] def apply(a: EntryType): Json = valueEncoder.apply(a.value) def apply(c: HCursor): Result[EntryType] = valueDecoder.apply(c).map(v => withValueOpt(v).getOrElse(createUnknown(v))) } }
Example 14
Source File: FinchAdapter.scala From caliban with Apache License 2.0 | 5 votes |
package caliban import caliban.Value.NullValue import io.circe.Decoder.Result import io.circe.Json import io.circe.syntax._ import io.circe.parser._ import io.finch._ import io.finch.circe._ import shapeless._ import zio.interop.catz._ import zio.{ Runtime, Task } object FinchAdapter extends Endpoint.Module[Task] { private def getGraphQLRequest( query: Option[String], op: Option[String], vars: Option[String], exts: Option[String] ): Result[GraphQLRequest] = { val variablesJs = vars.flatMap(parse(_).toOption) val extensionsJs = exts.flatMap(parse(_).toOption) val fields = query.map(js => "query" -> Json.fromString(js)) ++ op.map(o => "operationName" -> Json.fromString(o)) ++ variablesJs.map(js => "variables" -> js) ++ extensionsJs.map(js => "extensions" -> js) Json .fromFields(fields) .as[GraphQLRequest] } private def executeRequest[R, E]( request: GraphQLRequest, interpreter: GraphQLInterpreter[R, E], skipValidation: Boolean, enableIntrospection: Boolean )(implicit runtime: Runtime[R]) = runtime .unsafeRunToFuture( interpreter .executeRequest(request, skipValidation = skipValidation, enableIntrospection = enableIntrospection) .foldCause(cause => GraphQLResponse(NullValue, cause.defects).asJson, _.asJson) .map(gqlResult => Ok(gqlResult)) ) .future private val queryParams = (paramOption[String]("query") :: paramOption[String]("operationName") :: paramOption[String]("variables") :: paramOption[String]("extensions")).mapAsync { case (query :: op :: vars :: exts :: HNil) => Task.fromEither(getGraphQLRequest(query, op, vars, exts)) } def makeHttpService[R, E]( interpreter: GraphQLInterpreter[R, E], skipValidation: Boolean = false, enableIntrospection: Boolean = true )(implicit runtime: Runtime[R]): Endpoint[Task, Json :+: Json :+: CNil] = post(jsonBody[GraphQLRequest]) { request: GraphQLRequest => executeRequest(request, interpreter, skipValidation = skipValidation, enableIntrospection = enableIntrospection) } :+: get(queryParams) { request: GraphQLRequest => executeRequest(request, interpreter, skipValidation = skipValidation, enableIntrospection = enableIntrospection) } }
Example 15
Source File: package.scala From patchless with Apache License 2.0 | 5 votes |
package patchless import cats.syntax.either._ import io.circe.Decoder.Result import io.circe.{Decoder, HCursor, Json, JsonObject} import io.circe.generic.decoding.{DerivedDecoder, ReprDecoder} import io.circe.generic.encoding.{DerivedObjectEncoder, ReprObjectEncoder} import shapeless.{HList, LabelledGeneric} package object circe { implicit def decodeOptionOption[T]( implicit decodeOpt: Decoder[Option[T]] ) : Decoder[Option[Option[T]]] = { Decoder.instance { cursor => if(cursor.focus == Json.Null) { Right(Some(None)) } else decodeOpt.apply(cursor).map(Some(_)) } } implicit def decodePatch[T, U <: HList](implicit patchable: Patchable.Aux[T, U], decodeU: ReprDecoder[U] ): DerivedDecoder[Patch[T]] = new DerivedDecoder[Patch[T]] { def apply(c: HCursor): Result[Patch[T]] = decodeU(c).map { updates => Patch.ofUpdates[T, U](updates) } } implicit def encodePatch[T, U <: HList](implicit patchable: Patchable.Aux[T, U], encodeU: ReprObjectEncoder[U] ): DerivedObjectEncoder[Patch[T]] = new DerivedObjectEncoder[Patch[T]] { def encodeObject(a: Patch[T]): JsonObject = encodeU.encodeObject(a.patchUpdates) } }