From 6224b947308f9a1d54eaddeeadebf7673c561799 Mon Sep 17 00:00:00 2001 From: vbergeron Date: Fri, 20 Oct 2023 09:33:14 +0200 Subject: [PATCH] Support for circe KeyDecoder and KeyEncoder (#183) --- circe/src/io/github/iltotore/iron/circe.scala | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/circe/src/io/github/iltotore/iron/circe.scala b/circe/src/io/github/iltotore/iron/circe.scala index d19acd27..be1da32c 100644 --- a/circe/src/io/github/iltotore/iron/circe.scala +++ b/circe/src/io/github/iltotore/iron/circe.scala @@ -1,6 +1,6 @@ package io.github.iltotore.iron -import io.circe.{Decoder, DecodingFailure, Encoder, HCursor} +import io.circe.* /** * Implicit [[Encoder]]s and [[Decoder]]s for refined types. @@ -28,3 +28,27 @@ object circe: inline given[T](using mirror: RefinedTypeOps.Mirror[T], ev: Encoder[mirror.IronType]): Encoder[T] = ev.asInstanceOf[Encoder[T]] + + /** + * A [[KeyDecoder]] for refined types. Decodes to the underlying type then checks the constraint. + * + * @param decoder the [[KeyDecoder]] of the underlying type. + * @param constraint the [[Constraint]] implementation to test the decoded value. + */ + inline given [A, B](using inline decoder: KeyDecoder[A], inline constraint: Constraint[A, B]): KeyDecoder[A :| B] = + KeyDecoder.instance: input => + decoder.apply(input).flatMap[A :| B](_.refineOption) + + /** + * An [[KeyEncoder]] instance for refined types. Basically the underlying type [[KeyEncoder]]. + * + * @param encoder the [[KeyEncoder]] of the underlying type. + */ + inline given [A, B](using inline encoder: KeyEncoder[A]): KeyEncoder[A :| B] = encoder.asInstanceOf[KeyEncoder[A :| B]] + + inline given[T](using mirror: RefinedTypeOps.Mirror[T], ev: KeyDecoder[mirror.IronType]): KeyDecoder[T] = + ev.asInstanceOf[KeyDecoder[T]] + + inline given[T](using mirror: RefinedTypeOps.Mirror[T], ev: KeyEncoder[mirror.IronType]): KeyEncoder[T] = + ev.asInstanceOf[KeyEncoder[T]] +