Created
May 8, 2023 19:55
-
-
Save TAJD/a5e25500ea9db9555c4d2b30433bfd23 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.tajd | |
package metaprogramming | |
import java.nio.file.{Files, Path, Paths} | |
import org.scalafmt.interfaces.Scalafmt | |
import scala.jdk.CollectionConverters._ | |
import scala.meta.{Term, _} | |
import scala.util.Try | |
object CreateACaseClass extends App { | |
private case class ColumnSpecification( | |
colName: String, | |
colType: String | |
) | |
private case class CaseClass( | |
name: String, | |
fields: Seq[ColumnSpecification] | |
) | |
private case class ScalaFile( | |
name: String, | |
filePath: Path, | |
scalaCode: Source | |
) | |
private def createFields(fields: Seq[ColumnSpecification]): Seq[Term.Param] = | |
for { | |
field <- fields | |
} yield Term.Param( | |
Nil, | |
Term.Name(field.colName), | |
Some(Type.Name(field.colType)), | |
None | |
) | |
private def generateCode(caseClass: CaseClass): Source = { | |
val packageName = | |
Term.Select(Term.Name("metaprogramming"), Term.Name("generatedCode")) | |
val name = Type.Name(caseClass.name) | |
val fields = List(createFields(caseClass.fields).toList) | |
val parameters = Ctor.Primary( | |
Nil, | |
Name(""), | |
fields | |
) | |
val template = Template(Nil, Nil, Self(Name(""), None), Nil, Nil) | |
Source( | |
List( | |
Pkg( | |
packageName, | |
List( | |
Defn.Class( | |
List(Mod.Final(), Mod.Case()), | |
name, | |
Nil, | |
parameters, | |
template | |
) | |
) | |
) | |
) | |
) | |
} | |
private def readFile(filePath: Path): Seq[String] = | |
Files.readAllLines(Paths.get(filePath.toUri)).asScala.toSeq | |
private def writeScalaFile(scalaFile: ScalaFile): Try[Unit] = { | |
val path: Path = scalaFile.filePath.resolve(scalaFile.name ++ ".scala") | |
val rawContent = scalaFile.scalaCode.syntax | |
val config = | |
Paths.get(".scalafmt.conf") | |
val formattedContent = Scalafmt.create(this.getClass.getClassLoader).format(config, path, rawContent) | |
for { | |
_ <- Try(Files.createDirectories(path.getParent)) | |
_ <- Try(Files.write(path, formattedContent.getBytes)) | |
} yield () | |
} | |
private def getDataSourceSpec(lines: Seq[String]): Seq[ColumnSpecification] = | |
for { | |
line <- lines | |
} yield { | |
val values = line.split(",") | |
ColumnSpecification(values(0), values(1)) | |
} | |
private def generateCaseClassFile(filePath: String): Unit = { | |
val path = Paths.get(filePath) | |
val fileName = path.getFileName.toString | |
.replace(".csv", "") | |
val lines = readFile(path) | |
val dataSourceSpecification = getDataSourceSpec(lines) | |
val caseClassDefinition = CaseClass( | |
fileName, | |
dataSourceSpecification | |
) | |
val generatedClassAst = generateCode(caseClassDefinition) | |
val scalaFilePreGeneration = ScalaFile( | |
name = fileName, | |
filePath = path.getParent, | |
scalaCode = generatedClassAst | |
) | |
writeScalaFile(scalaFilePreGeneration) | |
} | |
generateCaseClassFile( | |
"""C:\Users\User\IdeaProjects\scalaSnippets\data\testData.csv""" | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment