Skip to content

Instantly share code, notes, and snippets.

@Leonti
Created April 1, 2019 08:01
Show Gist options
  • Save Leonti/07a5ef1497374cf520fc0a6137ace848 to your computer and use it in GitHub Desktop.
Save Leonti/07a5ef1497374cf520fc0a6137ace848 to your computer and use it in GitHub Desktop.
Print case classes from a nested structure
object Printing extends App {
trait Test {
val name: String
}
case class TestSingle(name: String, t: String, isOptional: Boolean) extends Test
case class NestedTest(name: String, fields: List[Test], isOptional: Boolean) extends Test
val testData = NestedTest("main", List(
TestSingle("field1", "Boolean", false),
TestSingle("field2", "String", true),
NestedTest("nestedField", List(
TestSingle("field3", "Boolean", false),
NestedTest("nestedFieldDeeper", List(
TestSingle("field4", "Awesome", true)
), true)
), false)
), true)
case class PrintField(name: String, typeName: String, isOptional: Boolean)
case class PrintClass(name: String, fields: List[PrintField])
def toPrintClasses(nested: NestedTest): List[PrintClass] = {
val result: List[(PrintField, List[PrintClass])] = nested.fields.map({
case TestSingle(name, value, isOptional) => (PrintField(name, value, isOptional), List())
case nested@NestedTest(name, _, isOptional) => {
(PrintField(name, name.capitalize, isOptional), toPrintClasses(nested))
}
})
val fieldsToPrint: List[PrintField] = result.map(_._1)
val classesToPrint = result.flatMap(_._2)
PrintClass(nested.name.capitalize, fieldsToPrint) :: classesToPrint
}
def printClass(toPrint: PrintClass): String = {
val fields = toPrint.fields.map(f => {
if (f.isOptional)
s"${f.name}: Option[${f.typeName}]"
else
s"${f.name}: ${f.typeName}"
}).mkString(",\n ")
s"""
|case class ${toPrint.name}(
| $fields
|)
""".stripMargin
}
def printClasses(toPrint: List[PrintClass]): String = {
toPrint.reverse.map(printClass).mkString("")
}
println(printClasses(toPrintClasses(testData)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment