zio / zio-json

Fast, secure JSON library with tight ZIO integration.
https://zio.dev/zio-json
Apache License 2.0
410 stars 147 forks source link

Scala3: Deriving a JsonDecoder for a type having a phantom type doesn't seem to work #1178

Open jivanic-demystdata opened 1 month ago

jivanic-demystdata commented 1 month ago

I have this code:

final case class Example[State <: ValidationState](a: String, b: Int) derives JsonDecoder

object Example {
  type UnvalidatedExample = Example[ValidationState.Unvalidated]
  type ValidatedExample   = Example[ValidationState.Validated]

  enum ValidationState {
    case Unvalidated, Validated 
  }
  object ValidationState {
    type Unvalidated = Unvalidated.type
    type Validated   = Validated.type
  }

  // Doesn't compile
  given JsonDecoder[UnvalidatedExample] = JsonDecoder[Example[?]].asInstanceOf[JsonDecoder[UnvalidatedExample]]
}

which fails to compile with error:

No given instance of type zio.json.JsonDecoder[com.example.Example[?]] was found for parameter a of method apply in object JsonDecoder.
johnhungerford commented 1 month ago

Why are you trying to summon the decoder instead of deriving it? This compiles:

import zio.json.*
import Example.ValidationState

final case class Example[State <: ValidationState](a: String, b: Int) derives JsonDecoder

object Example {
  type UnvalidatedExample = Example[ValidationState.Unvalidated]
  type ValidatedExample   = Example[ValidationState.Validated]

  enum ValidationState {
    case Unvalidated, Validated 
  }
  object ValidationState {
    type Unvalidated = Unvalidated.type
    type Validated   = Validated.type
  }

  given JsonDecoder[UnvalidatedExample] = DeriveJsonDecoder.gen[Example[?]].asInstanceOf[JsonDecoder[UnvalidatedExample]]
}
johnhungerford commented 1 month ago

Never mind -- I missed that it's the deriving bit you were asking about. Not sure why that doesn't work, as JsonDecoder.derived just calls DeriveJsonDecoder.gen.