Home > Software design >  Scala 2.13: Create Generic case class for variety of values
Scala 2.13: Create Generic case class for variety of values

Time:11-30

I have a JSON schema as shown below:

"elements": {
      "{element1Name}": {
        "value": "<p>The HTML content of the element.</p>",
        ":type": "text/html",
        "variations": {
          "{variation1Name}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          },
          "{variation2Name}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          },
          "{elementNName}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          }
        }
      },
      "{element2Name}": {
        "value": "<p>The HTML content of the element.</p>",
        ":type": "text/html",
        "variations": {
          "{variation1Name}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          },
          "{variation2Name}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          },
          "{elementNName}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          }
        }
      },
      "{elementNName}": {
        "value": "<p>The HTML content of the element.</p>",
        ":type": "text/html",
        "variations": {
          "{variation1Name}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          },
          "{variation2Name}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          },
          "{elementNName}": {
            "value": "<p>The HTML content of the element.</p>",
            ":type": "text/html"
          }
        }
      }
    }

Which I am able to replicate as following case classes:

case class AssetAPIEntity(
  value: String,
  @key(":type") `type`: Option[String] = None,
                         )
case class AssetAPIElements(
                             value: String,
                             @key(":type") `type`: Option[String] = None,
                             variations: Map[String,AssetAPIEntity]
                           )
case class AssetAPIData(
  title: Option[String] = None,
  description: Option[String] = None,
  @key("cq:Model") cqModel: String,
  elements: Map[String,AssetAPIElements]
                       )

Now the problem is that field value could be either of these:

  1. Single Number
  2. Single Boolean
  3. Single String
  4. Multi Number
  5. Multi Boolean
  6. Multi String

I am stuck at point where how can I write a generic syntax to incorporate any of these values? Can someone help? I thought of ADTs but not sure about the syntax. I would want something like this:

case class AssetAPIEntity[T](
  value: String,
  @key(":type") `type`: Option[T] = None,
                         )

or in simple terms:

case class AssetAPIEntity(
  value: String,
  @key(":type") `type`: Option[String | Boolean | Number | Seq[String] | Seq[Boolean] | Seq[Number]] = None,
                         )

CodePudding user response:

case class AssetAPIEntity[T](
  value: String,
  `type`: Option[T] = None
) 

seems to be valid Scala syntax.

case class AssetAPIEntity(
  value: String, 
  `type`: Option[String | Boolean | Number | Seq[String] | Seq[Boolean] | Seq[Number]] = None
) 

is Scala 3 syntax: https://docs.scala-lang.org/scala3/reference/new-types/union-types.html

In Scala 2 this corresponds to

case class AssetAPIEntity(value: String, `type`: Option[FieldType]) 

// ADT
sealed trait FieldType 
case class Str(s: String) extends FieldType 
case class Bool(b: Boolean) extends FieldType 
case class Num(i: Int) extends FieldType 
case class Strs(ss: Seq[String]) extends FieldType 
case class Bools(bs: Seq[Boolean]) extends FieldType 
case class Nums(is: Seq[Int]) extends FieldType 

How to define "type disjunction" (union types)? Solutions: sealed trait hierarchy, union types (first-class in Scala 3 or different emulations in Scala 2), type classes, shapeless.Coproduct, Either.

  • Related