Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 20 15:23
    feoktant commented #726
  • Oct 20 08:41
    travisbrown closed #1529
  • Oct 20 08:39

    travisbrown on master

    Update refined, refined-scalach… (compare)

  • Oct 20 08:39
    travisbrown closed #1541
  • Oct 20 08:35

    travisbrown on master

    Update sbt-scalajs, scalajs-com… (compare)

  • Oct 20 08:35
    travisbrown closed #1550
  • Oct 20 08:33
    travisbrown closed #1556
  • Oct 20 08:33

    travisbrown on master

    Update sbt-mima-plugin to 0.8.1… (compare)

  • Oct 20 08:33

    travisbrown on master

    Update sbt-dotty to 0.4.4 (#155… (compare)

  • Oct 20 08:33
    travisbrown closed #1555
  • Oct 20 08:28

    travisbrown on master

    Update sbt to 1.4.1 (#1557) (compare)

  • Oct 20 08:28
    travisbrown closed #1557
  • Oct 19 22:41
    scala-steward closed #1547
  • Oct 19 22:41
    scala-steward review_requested #1557
  • Oct 19 22:41
    scala-steward opened #1557
  • Oct 19 18:23
    scala-steward review_requested #1556
  • Oct 19 18:23
    scala-steward opened #1556
  • Oct 18 16:30
    codecov-io commented #1555
  • Oct 18 16:27
    codecov-io commented #1555
  • Oct 18 16:14
    scala-steward closed #1554
Sait Sami Kocataş
@Deliganli

hi everyone

how can one create domain models for such responses below?

{
    "wrapper": {
        "results": 2,
        "dynamicKey": [
            "Item1",
            "Item2"
        ]
    }
}

{
    "wrapper": {
        "results": 1,
        "someOtherKey": {
            "different":"object"
        }
    }
}

what I am trying to do is like below;

case class DomainResponse[T](results:Long, body:T)

object DomainResponse {
    def decoder[B:Decoder](key:String): Decoder[DomainResponse[B]] = Decoder.instance { c =>
      for {
        results <- c.downField("wrapper").downField("results").as[Long]
        body   <- c.downField("wrapper").downField(key).as[B]
      } yield DomainResponse(results, body)
    }
}

case class Endpoint1Body(???)

object Endpoint1Body {
    implicit val decoder: Decoder[Endpoint1Body] = deriveDecoder
}

client.get(uri / "someEndpoint")(_.attemptAs[DomainResponse[Endpoint1Body]])

not sure how I should create the decoder since the key is dynamic

Jacob Wang
@jatcwang
@Deliganli I assume Endpoint1Body is the [ "Item1", "Item2" ] part?
Sait Sami Kocataş
@Deliganli
yes, and imagine there will be Endpoint2Body and it will be someOtherKey
Sait Sami Kocataş
@Deliganli
I am doing something like this now but have no idea what would be good way
def dsl[F[_]: Sync](client: Client[F], config: DomainConfig): F[Domain[F]] =
    Sync[F].delay {
      implicit val endpoint1Decoder: Decoder[DomainResponse[Endpoint1Body]] = DomainResponse.decoder[Endpoint1Body]("dynamicKey")

      new Domain[F] {
        def endpoint1: F[DomainResponse[Endpoint1Body]] = {
          val request = Request[F](
            Method.GET,
            config.uri / "endpoint1"
          )

          client.expect[DomainResponse[Endpoint1Body]](request)
        }
      }
    }
Jacob Wang
@jatcwang
you're better off getting rid of the DomainResponse class/decoder altogether I think, and provide a function (much like DomainResponse.decoder). For example:
object Endpoint1Body {
def wrapperDecoder[B](bDecoder: Decoder[B], key:String): Decoder[B] = Decoder.instance { c =>
      for {
        results <- c.downField("wrapper").downField("results").as[Long]
        body   <- c.downField("wrapper").downField(key).as[B](bDecoder)
      } yield DomainResponse(results, body)
    }

val endpoint1BodyInnerDecoder = deriveDecoder[Endpoint1Body]

implicit val decoder: Decoder[Endpoint1Body] = wrapperDecoder(endpoint1BodyInnerDecoder, "dynamicKey") 
}
Ben Shaw
@benshaw

use deriveUnwrappedCodec instead of deriveCodec

Where is this function i cant find it or any reference to it

Jacob Wang
@jatcwang
@benshaw io.circe.generic.extras.semiauto#deriveUnwrappedCodec
Soren
@srnb_gitlab
java.lang.NullPointerException
        at io.circe.Printer$PrintingFolder.onString(Printer.scala:320)
        at io.circe.Printer$PrintingFolder.onString(Printer.scala:303)
        at io.circe.Json$JString.foldWith(Json.scala:359)
        at io.circe.JsonObject$LinkedHashMapJsonObject.appendToFolder(JsonObject.scala:343)
        at io.circe.Printer$PrintingFolder.onObject(Printer.scala:370)
        at io.circe.Printer$PrintingFolder.onObject(Printer.scala:303)
        at io.circe.Json$JObject.foldWith(Json.scala:421)
        at io.circe.JsonObject$LinkedHashMapJsonObject.appendToFolder(JsonObject.scala:343)
        at io.circe.Printer$PrintingFolder.onObject(Printer.scala:370)
        at io.circe.Printer$PrintingFolder.onObject(Printer.scala:303)
        at io.circe.Json$JObject.foldWith(Json.scala:421)
        at io.circe.Printer$PrintingFolder.onArray(Printer.scala:356)
        at io.circe.Printer$PrintingFolder.onArray(Printer.scala:303)
        at io.circe.Json$JArray.foldWith(Json.scala:390)
        at io.circe.JsonObject$MapAndVectorJsonObject.appendToFolder(JsonObject.scala:450)
        at io.circe.Printer$PrintingFolder.onObject(Printer.scala:370)
        at io.circe.Printer$PrintingFolder.onObject(Printer.scala:303)
        at io.circe.Json$JObject.foldWith(Json.scala:421)
        at io.circe.Printer.print(Printer.scala:194)
        at io.circe.Json.spaces2(Json.scala:128)
On 0.13.0
I'm guessing this means I have a string value of null somewhere?
Soren
@srnb_gitlab
Found the nulls :/
Unfortunately they're out of my control
Soren
@srnb_gitlab
Alternatively, I could make the semiauto derivation check everything for null. Is that possible?
Jacob Wang
@jatcwang
Not that I know of. I think you'll have to create another case class with all the fields being Option[..] and implement a conversion
Soren
@srnb_gitlab
I'm not converting I'm just gonna publishLocal a patch I think
That is, if I can without SBT yelling at me
I've found a coursier bug in the midst of this :(
Basti
@lunaryorn
Is there a built-in way to make a case class decoder fail if there are extra fields in the JSON? Currently I'm using a Decoder.forProductN and an extra .validate call, but repeating the field names in .validate becomes tedious, so I'm hoping for some built-in way.
ritschwumm
@ritschwumm
afaik there isn't - can you maybe just check that the number of fields is exactly the same as you expect instead of repeating names somehow?
this is what you want, right? circe/circe#374
that links to circe/circe#1117 so maybe i'm wrong and it is supported by now.
ComFreek
@ComFreek
@jatcwang Why does the following fail?
import io.circe.generic.auto._
import io.circe.generic.semiauto._

import io.circe.generic.extras.auto._
import io.circe.generic.extras.semiauto._

sealed abstract class Foo(val label: String)
sealed case class Bar(override val label: String) extends Foo(label)

val t: Encoder[Foo] = deriveConfiguredEncoder
I've reduced my above problem to that
ComFreek
@ComFreek
Ah, circe doesn't support encoding abstract classes conveniently?
What's the preferred approach then?
I only need the abstract class for programming -- for (de)serialization I just want to (de)serialize all the concrete child case classes
Jacob Wang
@jatcwang
@ComFreek do you have a Configuration in scope?
you need it if you want to use deriveConfiguredEncoder
(also, keep only import io.circe.generic.extras.semiauto._. That's all you need in this example)
ComFreek
@ComFreek
oh damn, I had to Configurations in scope
Jacob Wang
@jatcwang
basically if you're using circe-generic-extras package, you don't really need circe-generic as the former is a superset (just slower to compile I guess because it has more features)
ComFreek
@ComFreek
Is there really no good way to debug why deriveConfiguredEncoder fails?

basically if you're using circe-generic-extras package, you don't really need circe-generic as the former is a superset (just slower to compile I guess because it has more features)

alright, thanks

ComFreek
@ComFreek
whaaaaaaaaaat
circe is kidding me...
so I had a @ConfiguredJsonCodec sealed abstract class Foo(...) { ... } with object Foo { ... } and @ConfiguredJsonCodec sealed case class Bar(...) { ... } with object Bar { ... } and Circe would fail on val enc: Encoder[Foo] = deriveConfiguredEncoder.
After removing the companion objects, it worked.
Jacob Wang
@jatcwang
huh interesting... @ConfiguredJsonCodec should generally work but I don't use it much so ..
ComFreek
@ComFreek
also, deriveConfiguredEncoder only works if there's a Configuration available. This might seem obvious, but that wasn't the case with deriveEncoder, which is marked deprecated in favor of the former
so at least a note would have been nice
Jacob Wang
@jatcwang
@ComFreek it has always been the case for io.circe.generic.extras.deriveEncoder. The reason why it probably used to work is because you were using io.circe.generic.deriveEncoder which doesn't not require a Configuration
The reason why it is deprecated is precisely because the name clashes and causes trouble :)
ComFreek
@ComFreek
aaah
that is a bit confusing to newcomers :-)
Jacob Wang
@jatcwang

Yeah the worst is the error messages because it's unclear whether you're missing a Configuration in scope or an encoder/decoder instance for one of your fields. Oh and duplicate implicits will trigger the same error too :D

This is a scala issue in general (with missing implicits). Super happy it's fixed in Scala 3

ComFreek
@ComFreek
suggestion: the deprecation message on generic.extras.derive{Encoder, Decoder} could make clear that deprecation only applies to those from the extras package.
Jacob Wang
@jatcwang
I'm not the maintainer, but I'm sure a small PR would be welcomed!
Alexandre DUVAL
@KannarFr
Hi, there is a simple way to decode java.util.Optional<T> ?