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:
- Single Number
- Single Boolean
- Single String
- Multi Number
- Multi Boolean
- 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
.