Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example in readme failing #63

Open
flyrev opened this issue Apr 21, 2016 · 4 comments
Open

Example in readme failing #63

flyrev opened this issue Apr 21, 2016 · 4 comments

Comments

@flyrev
Copy link

flyrev commented Apr 21, 2016

import argonaut.Shapeless._
import argonaut.{DecodeJson, DecodeResult, EncodeJson, _}

object ArgonautPlaying extends App {
   case class CC(i: Int, s: String)

   // encoding
   val encode = EncodeJson.of[CC]

   val json = encode(CC(2, "a"))
   json.nospaces == """{"i":2,"s":"a"}"""

   // decoding
   val decode = DecodeJson.of[CC]

   val result = decode.decodeJson(json)
   result == DecodeResult.ok(CC(2, "a"))
}
<dependencies>
    <dependency>
        <groupId>org.scala-lang</groupId>
        <artifactId>scala-library</artifactId>
        <version>2.11.8</version>
    </dependency>

    <dependency>
        <groupId>io.argonaut</groupId>
        <artifactId>argonaut_2.11</artifactId>
        <version>6.2-M1</version>
    </dependency>

    <dependency>
        <groupId>com.github.alexarchambault</groupId>
        <artifactId>argonaut-shapeless_6.1_2.11</artifactId>
        <version>1.1.0-RC1</version>
    </dependency>
</dependencies>

Errors:

Error:(15, 29) could not find implicit value for evidence parameter of type argonaut.DecodeJson[ArgonautPlaying.CC]
val decode = DecodeJson.of[CC]
^
Error:(15, 29) not enough arguments for method of: (implicit evidence$1: argonaut.DecodeJson[ArgonautPlaying.CC])argonaut.DecodeJson[ArgonautPlaying.CC].
Unspecified value parameter evidence$1.
val decode = DecodeJson.of[CC]
^

@alexarchambault
Copy link
Owner

argonaut-shapeless only works with argonaut 6.1 for now. I'm running into problems with the covariance of DecodeJson when trying to port it to argonaut 6.2 for now.

@janstenpickle
Copy link

I have observed same issue. In attempt to trace the problem I created a new project with just this library as a dependency.

My build.sbt:

name := "Argonaut Shapeless Test"

version := "0.1"

scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  "com.github.alexarchambault" %% "argonaut-shapeless_6.1" % "1.1.0-RC2"
)

The test class:

import argonaut._, Argonaut._, Shapeless._

object Test {
  sealed trait Base
  case class First(i: Int) extends Base
  case class Second(s: String) extends Base

  // encoding
  val encode = EncodeJson.of[Base]

  val json = encode(First(2))
  json.nospaces == """{"First":{"i":2}}"""

  // decoding
  val decode = DecodeJson.of[Base]

  val result = decode.decodeJson(json)
  result == DecodeResult.ok(First(2))
}

Errors on compiling:

[info] Set current project to Argonaut Shapeless Test (in build file:/private/tmp/test/)
[info] Compiling 1 Scala source to /private/tmp/test/target/scala-2.11/classes...
[error] /private/tmp/test/src/main/scala/Test.scala:9: could not find implicit value for evidence parameter of type argonaut.EncodeJson[Test.this.Base]
[error]   val encode = EncodeJson.of[Base]
[error]                             ^
[error] /private/tmp/test/src/main/scala/Test.scala:15: could not find implicit value for evidence parameter of type argonaut.DecodeJson[Test.this.Base]
[error]   val decode = DecodeJson.of[Base]
[error]                             ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed

However it seems odd that pasting the following into the console works:

import argonaut._, Argonaut._, Shapeless._

sealed trait Base
case class First(i: Int) extends Base
case class Second(s: String) extends Base

// encoding
val encode = EncodeJson.of[Base]
val json = encode(First(2))
json.nospaces == """{"First":{"i":2}}"""

// decoding
 val decode = DecodeJson.of[Base]

val result = decode.decodeJson(json)
result == DecodeResult.ok(First(2))

Changing where the model classes are declared to outside of the test class works:

import argonaut._, Argonaut._, Shapeless._

sealed trait Base
case class First(i: Int) extends Base
case class Second(s: String) extends Base

object Test {

  // encoding
  val encode = EncodeJson.of[Base]

  val json = encode(First(2))
  json.nospaces == """{"First":{"i":2}}"""

  // decoding
  val decode = DecodeJson.of[Base]

  val result = decode.decodeJson(json)
  result == DecodeResult.ok(First(2))
}

But this doesn't:

import argonaut._, Argonaut._, Shapeless._

object Model {
  sealed trait Base
  case class First(i: Int) extends Base
  case class Second(s: String) extends Base
}

object Test {
  // encoding
  val encode = EncodeJson.of[Base]

  val json = encode(First(2))
  json.nospaces == """{"First":{"i":2}}"""

  // decoding
  val decode = DecodeJson.of[Base]

  val result = decode.decodeJson(json)
  result == DecodeResult.ok(First(2))
}

This is all because of the way macros work and compile order (Shapless uses macros to fill in the implicits here). It works in the REPL because everything is ordered and compiled on the fly, however when using scalac things can get compiled in different orders, and break the macro's compile phase as the classes that it is looking for aren't there.

I would recommend that the best way around this is to have the model classes in a separate module to the JSON parsing, that way the model classes will always be built first and the code will compile.

Would it be worth an update to the readme to describe this behaviour (I'm happy to raise a PR)?

@alexarchambault
Copy link
Owner

@janstenpickle If you want to add a word about this issue (this is the classic SI-7046, aka SI-7755), go for it! Putting the models and the codec derivations in different projects is indeed the most reliable way of addressing that afaik.

@alexarchambault
Copy link
Owner

If you change the README, change the one under doc/, then run sbt tut. The latter will update the README at the root of the project. You can then commit both READMEs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants