Skip to content

Latest commit

 

History

History
55 lines (41 loc) · 2.03 KB

parameterized.md

File metadata and controls

55 lines (41 loc) · 2.03 KB

Parameterized Classes

ScalaJack is able to handle parameterized classes and traits seamlessly:

File1.scala

package com.me
sealed trait Vehicle[T]{ val  transported:T }
case class Car(transported:Person) extends Vehicle[Person]

File2.scala

given sjVehicle: ScalaJack[Vehicle[Person]] = sjCodecOf[Vehicle[Person]]
println(sjVehicle.toJson(Car(Person("Fred",25))))
// {"_hint":"Car","transported":{"name":"Fred","age":25}}

Ok, now let's make it interesting..

File1.scala

object VehicleClass extends Enumeration {
  type VehicleClass = Value
  val Land, Air, Sea = Value
}
import VehicleClass.*

sealed trait Vehicle { val kind: VehicleClass }
case class Car(passengers: Int) extends Vehicle { val kind: Land.type = Land }

sealed trait Hobby[X, Y] { val thing1: X; val thing2: Y }
sealed trait Artist[W, Z] { val instrument: W; val effort: Z }
sealed trait Person[X, Y] { val who: X; val org: Y }

case class Sports[A, B](thing1: A, thing2: B) extends Hobby[A, B]
case class Painter[A, B](instrument: A, effort: B) extends Artist[A, B]
case class Employee[A, B, C, D](who: Artist[C, Hobby[D, A]], org: B) extends Person[Artist[C, Hobby[D, A]], B]
type ComplexPerson = Person[Artist[Int, Hobby[Double, Char]], Vehicle]

File2.scala

given sjPerson: ScalaJack[ComplexPerson] = sjCodecOf[ComplexPerson]
val  inst: ComplexPerson = Employee(Painter(5, Sports(1.2, 'Z')), Car(4))
val  js = sjPerson.toJson(inst)

// {"_hint":"Employee","who":{"_hint":"Painter","instrument":5,"effort":{"_hint":"Sports","thing1":1.2,"thing2":"Z"}},"org":{"_hint":"Car","passengers":4}}

sjPerson.fromJson(js) // re-constitutes inst

Clearly this is a contrived example, but it does show that complex nesting relationships between parameterized types work just fine, even when we threw in some traits and an Enumeration for good measure. Remember that you always have control of ScalaJack's reading and rendering. You can force a more general trait (will generate type hints) or use a specific concrete class (won't need type hints).