eed3si9n / sjson-new

a typeclass based JSON codec that's backend independent
Apache License 2.0
36 stars 19 forks source link

LListOps does not work with Scala 3 #125

Closed xuwei-k closed 2 years ago

xuwei-k commented 2 years ago

because Scala 3 generate _1, _2 methods for case classes. LCons is case class 😇

Welcome to Scala 3.1.1-RC1 (1.8.0_312, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> case class A(x1: Int, x2: String)
val a // defined case class A

scala> val a = A(2, "b")
val a: A = A(2,b)

scala> a._1
val res0: Int = 2

scala> a._2
val res1: String = b

scala> a._3
-- [E008] Not Found Error: -----------------------------------------------------
1 |a._3
  |^^^^
  |value _3 is not a member of A
1 error found

scala> implicit class AOps(self: A) { def _1 = "AOps._1" }
// defined class AOps
def AOps(self: A): AOps

scala> a._1
val res2: Int = 2
-final case class LCons[A1: JsonFormat: ClassTag, A2 <: LList: JsonFormat](name: String, head: A1, tail: A2) extends LList {
+final class LCons[A1: JsonFormat: ClassTag, A2 <: LList: JsonFormat](val name: String, val head: A1, val tail: A2) extends LList with Product with Serializable with Equals {
+  override def canEqual(that: Any): Boolean = that.isInstanceOf[LCons[_, _]]
+  override def productArity: Int = 3
+  override def productElement(n: Int): Any = n match {
+    case 0 => name
+    case 1 => head
+    case 2 => tail
+    case _ => throw new IndexOutOfBoundsException(Integer.toString(n))
+  }
+  def copy[B1: JsonFormat: ClassTag, B2 <: LList: JsonFormat](name: String = name, head: B1 = head, tail: B2 = tail): LCons[B1, B2] =
+    new LCons[B1, B2](name, head, tail)
+
+  override def hashCode(): Int = scala.runtime.ScalaRunTime._hashCode(this)
+
+  override def equals(x$1: Any): Boolean = x$1 match {
+    case that: LCons[_, _] =>
+      (this.name == that.name) && (this.head == that.head) && (this.tail == that.tail)
+    case _ =>
+      false
+  }
+
   def :*:[B1: JsonFormat: ClassTag](labelled: (String, B1)): B1 :*: A1 :*: A2 = LCons(labelled._1, labelled._2, this)
   override def toString: String = s"($name, $head) :*: $tail"
+  override def productPrefix: String = "LCons"
   override def find[B1: ClassTag](n: String): Option[B1] =
     if (name == n && implicitly[ClassTag[A1]] == implicitly[ClassTag[B1]]) Option(head match { case x: B1 @unchecked => x })
     else tail.find[B1](n)
   override def fieldNames: List[String] = name :: tail.fieldNames
 }

+object LCons extends Serializable {
+  override def toString: String = "LCons"
+  def apply[A1: JsonFormat: ClassTag, A2 <: LList: JsonFormat](name: String, head: A1, tail: A2): LCons[A1, A2] =
+    new LCons[A1, A2](name = name, head = head, tail = tail)
+  def unapply[A1, A2 <: LList](x$0: LCons[A1, A2]): Option[(String, A1, A2)] =
+    if (x$0 == null) {
+      None
+    } else {
+      Some((x$0.name, x$0.head, x$0.tail))
+    }
+}
xuwei-k commented 2 years ago
eed3si9n commented 2 years ago

interesting find. I'm fine with avoiding case class.

eed3si9n commented 2 years ago

Fixed in https://github.com/eed3si9n/sjson-new/pull/127